2010-09-30 4 views
3

Il y a une classe comme ceci:opérateur [] surcharge

class X { 
    public: 
     ... 
    private: 
     int changeable[3]; 
     int unchangeable[3]; 
};  

Et ceci est son utilisation souhaitable:

X x; 
x[0] = 1; // here changeable[0] should be used 
a = x[0]; // here unchangeable[0] should be used 

Est-il possible de définir operator[] dans class X à mettre en œuvre que?

+0

Vous pouvez mettre en œuvre le premier cas, vous pouvez mettre en œuvre le second cas, mais pas les deux ensemble – Gaim

+0

Il peut surcharger l'opérateur et il peut choisir en fonction du contexte. – JSchlather

Répondre

3

je serais probablement résoudre cela avec un objet proxy:

class Xproxy 
{ 
    int& changeable; 
    int& unchangeable; 

    Xproxy(int& c, int& u) : changeable(c), unchangeable(u) 
    {} 

    Xproxy& operator=(int i) 
    { 
    changeable=i 
    return *this 
    } 

    operator int() 
    { 
    return unchangeable; 
    } 
}; 


class X 
{ 
    int changeable[3]; 
    int unchangeable[3]; 

    Xproxy operator[](int i) 
    { 
    return Xproxy(changeable[i], unchangeable[i]) 
    } 
}; 

Alors maintenant, lorsque vous appelez l'opérateur [] sur X, vous obtenez un objet Xproxy qui a des références à l'intérieur à la fois les champs modifiables et invariables .

Si vous essayez d'assigner à l'objet Xproxy, il appellera l'opérateur = qui assigne à la référence à l'objet modifiable. Si vous essayez d'affecter l'objet Xproxy à un int, il appelle l'opérateur de distribution qui extrait le champ non modifiable.

2

Sorte de, mais vous devez être sournois.

class X { 
private: 
    class XIndex; 
public: 
    XIndex operator[](int); 
    //... 
}; 

class X::XIndex { 
public: 
    operator int() const; 
    void operator=(int val); 
private: 
    friend class X; 
    XIndex(int* lvalue, int const* rvalue); 

    int* _lval; 
    int const* _rval; 

    // Disallow copy and assignment. 
    XIndex(const XIndex&); 
    XIndex& operator=(const XIndex&); 
}; 

X::XIndex X::operator[](int i) { 
    // Check array bound? 
    return XIndex(&changeable[i], &unchangeable[i]); 
} 

// Implementation of X::XIndex methods is an exercise. 

Notez que si les x [num] expression apparaît un autre endroit que immédiatement à la gauche un opérateur =, le « rvalue » est utilisé. Vous pouvez également ajouter operator+=, operator*=, etc. si vous le souhaitez.

+1

Oh, et vous savez que l'idée même de faire tout cela est considérée comme une mauvaise forme, n'est-ce pas? – aschepler

+0

Ouais! C'est très pratique à utiliser. – 01d

0

Je pense avoir une "sorte de" solution. Ce n'est pas une exacte solution au problème posé, cependant, je crois, c'est plus d'utilisation pratique.

L'idée est simplement que, une variable const X entraînerait l'accès unchangeable_, une variable non-const X entraînerait l'accès changeable_.

class X { 
    public: 
    const int & operator[](int index) const { 
     cout << __PRETTY_FUNCTION__ << " index = " << index << "\n"; 
     return unchangeable_[ index ]; 
    } 

    int & operator[](int index) { 
     cout << __PRETTY_FUNCTION__ << " index = " << index << "\n"; 
     return changeable_[ index ]; 
    } 

    private: 
    int changeable_[ 3 ]; 
    int unchangeable_[ 3 ]; 
}; 

void foo(X const & x1) { 
    int a = x1[ 1 ]; // reading from x 
} 

int main() { 
    X x; 

    x[ 0 ] = 1;   // writing to x 
    int a = x[ 1 ];  // reading from x 

    foo(x); 
} 

La sortie est:

int& X::operator[](int) index = 0 
int& X::operator[](int) index = 1 
const int& X::operator[](int) const index = 1 
Questions connexes