2015-08-10 14 views
5

Wenn ich eine const-Referenz zu einem anderen Mitglied verwende, ist es möglich, dass diese Referenz ungültig wird?Sind const Verweise auf Mitglieder sicher

class Class { 
public: 
    const int &x{y}; 
private: 
    int y; 
}; 

Zum Beispiel wenn ich Instanzen dieser Klasse in einem Vektor , die nach einem push_back seine Kapazität erhöht. Gemäß dem Standard werden alle Iteratoren und Referenzen ungültig, wenn ein Vektor seine Kapazität erhöhen muss. Ist die Referenz danach noch gültig?

+0

Ich wäre überrascht, wenn man das in einen Vektor drücken könnte und haben 'X' Punkt, wo Sie denken, es tut. –

+0

Sollte kein Pushback für jede neu eingefügte 'Class'-Instanz in Ordnung sein? Die Daten werden in den Vektor kopiert, wobei x auf die neue y-Position zeigt. – 0ax1

+0

Wenn Sie die Referenz vor 'push_back()' genommen haben, wird nicht auf dieses Element innerhalb des Vektors verwiesen. 'push_back()' nimmt eine Kopie. –

Antwort

6

Dies ist derzeit nicht sicher, wie wenn Sie eine Instanz von Class kopieren, x die y des kopierten Objekt verweisen, das ist nicht eigene y. Sie können dies sehen, indem Sie den folgenden Code ausführen:

int main() 
{ 
    Class a{}; 
    std::vector<Class> vec; 
    vec.push_back(a); 

    //these lines print the same address 
    std::cout << &(a.x) << std::endl; 
    std::cout << &(vec[0].x) << std::endl; 
} 

Sie dieses Problem beheben können Ihre eigenen Kopierkonstruktor und Zuweisungsfunktionen durch das Schreiben korrekt x initialisieren:

Class (const Class& rhs) : x{y}, y{rhs.y} {} 

Dies ist sicher, weil x und y wird nur zusammen mit deinem Objekt zerstört. Die Ungültigkeits Referenzen für std::vector bedeutet Verweise auf die Vektorelemente:

Class c; 
std::vector<Class> vec; 
vec.push_back(c); 

Class& cr = vec[0]; 
//other operations on vec 
std::cout << c.x; //fine, that reference is internal to the class 
std::cout << cr.x; //cr could have been invalidated 
+1

Funktioniert es immer noch, wenn ich die Kopie ctor überschreibe und der Vektor nach einem Pushback wachsen muss? Sind die Referenzen dann noch gültig? – 0ax1

+0

Ja, das ist der letzte Absatz und die Snippet-Adresse. – TartanLlama

3

Angenommen, dies ist ein Verweis auf ein anderes Mitglied derselben Instanz, müssen Sie den Kopierkonstruktor überschreiben, um ihn zu initialisieren. Der Standardkopiekonstruktor kopiert den Verweis auf 'y' von der alten Instanz, die ungültig sein könnte.

Warum brauchen Sie einen Verweis auf ein Mitglied ist eine andere Frage.

P.S. Außerdem müssen Sie einen Zuweisungsoperator aus dem gleichen Grund überschreiben.

+0

Ich dachte darüber nach, als eine Alternative zum gewöhnlichen Getter. – 0ax1

Verwandte Themen