2012-03-30 3 views
2

Ich möchte eine Klasse myVector definieren, die sowohl die Zuweisung operator= als auch den Klammerzugriff z. B. myclass(1) = 0.5 unterstützt. Sehen Sie ein Dummy-Beispiel untenÜberladungszuweisung und runden Klammernoperator in C++

class myVector 
{ 
public: 
    vector<double> _v; 
    myVector(unsigned int size) : _v(size, 0) { } 

    double& operator()(int i) 
    { 
     return _v[i]; 
    } 

    unsigned int size() const { return _v.size(); } 

    myVector& operator=(const myVector& v) 
    { 
     _v.resize(v.size()); 
     for(int i=0;i<v.size();i++) 
      _v[i] = v(i); 
    } 
} 

Dieser Code nicht da () kompiliert werden kann, ist nicht als konstante Funktion definiert. Dies liegt daran, dass ich die direkte Zuweisung wie myvector(1) = 2 aktivieren möchte. Um dieses Problem zu lösen, kann ich nur an zwei Lösungen denken. Man soll etw. Definieren. wie double getValue(int i) const, aber das scheint seltsam, da einige doppelte Code hinzugefügt wird. Die andere ist const aus der Signatur () Funktion zu entfernen, aber das ist auch nicht wünschenswert. Ich bin mir sicher, dass es eine gute Arbeit geben wird, aber ich kann es nicht finden.

+1

Warum so kompliziert - Sie können einfach sagen '_v = v;', oder '_v.swap (v);'. –

+5

diese runden Klammern werden "Klammern" genannt, und der Operator heißt "der Funktionsaufruf-Operator" –

+0

Dies ist fast ein exaktes Duplikat einer früheren Frage. http://stackoverflow.com/questions/5762042/const-overloaded-operator-function-and-its-invocation/5762323. [Meine Antwort] (http://stackoverflow.com/a/5762323/179910) gilt auch hier. –

Antwort

2

Die richtige Lösung ist "beide". Elementfunktionen, einschließlich Operatoren, können unter const -ness überladen werden (der Zeiger this ist effektiv ein Parameter und beteiligt sich an der Überladungsauflösung).

double& operator()(int i) { return _v[i]; } 
double operator()(int i) const { return _v[i]; } 

HINWEIS: Bei Drittbetreibern, das linke Objekt ist nicht nur wie ein Parameter, es ist ein Parameter.

+0

Danke, es ist sehr hilfreich. –

0

Für den besonderen Fall des Operators(), sollten Sie nur zwei Überlastungen bieten:

double& operator()(int i) { return _v[i]; } 
double operator()(int i) const { return _v[i]; } // [1] 

Wenn dies ein Templat-Behälter war, der zweite Überlastung eine const& zurückkehren würde, aber wenn man bedenkt, dass es ein double ist Die Rückgabe einer Kopie ist in Ordnung.

nun als Empfehlung, können Sie die Copykonstruktor, implementieren und implementieren dann eine einfache swap Funktion:

void myVector::swap(myVector & lhs) { 
    _v.swap(lhs._v); 
} 

Mit diesen beiden Werkzeugen vorhanden, dann können Sie die idiomatische Implementierung von operator= verwenden:

myVector& myVector::operator=(myVector rhs) { // by value 
    swap(*this, rhs); 
    return *this; 
} 

Die andere Sache ist, dass es keinen Sinn macht, Ihre eigene Schleife zu rollen, die Vektoren zu kopieren, wissen, dass sie bereits, wie das tun, indem sie sich selbst, so _v = v._v; hat den gleichen Effekt wie Ihre Schleife.