2016-03-28 2 views
0

Für deduktiven Gründen schrieb ich einen Code wie folgt:Rückkehr ein Klassenmitglied Referenzvariable Ergebnisse in Laufzeitfehler

class Bike 
{ 
public: 
    Bike(std::string name) : m_name(name) {} 
    std::string& getName() const { return m_name; } 
private: 
    std::string& m_name; 
}; 

int main() { 
    string name("Trek"); 
    Bike bike(name); 

    string& ref1 = name; 
    string& ref2 = ref1; 
    string& ref3 = bike.getName(); // <Error reading characters of string> why? 

    cout << ref1 << endl; // ok 
    cout << ref2 << endl; // ok too 
    cout << ref3 << endl; // Boom. runtime error 

    return 0; 
} 

Kann jemand bitte die Gründe für dieses Verhalten erklären?

Antwort

2

Kann jemand bitte die Gründe für dieses Verhalten erklären?

Sie speichern einen Verweis auf ein Objekt, das nach Abschluss des Konstruktors nicht aktiv ist. Sie speichern eine hängende Referenz.

Bike(std::string name) : m_name(name) {} 
       ^^^^^ 

name ist eine Variable auf dem Stapel. Es ist nicht aktiv, nachdem die Funktion zurückkehrt.

Um eine gültige Referenz zu erhalten, muss das Argument Bike() als Referenz übergeben werden.

Bike(std::string& name) : m_name(name) {} 
       ^^ 
1

Ihr Konstruktor nimmt eine Zeichenfolge nach Wert. Es ist also eine Kopie, die lokal für die Funktion ist. Diese Zeichenfolge wird am Ende der Funktion zerstört, wodurch die Referenz ungültig wird. Wenn Sie einen Verweis auf eine Zeichenfolge in Ihrem Objekt speichern möchten (und Sie wirklich sicher sind, dass Sie das tun möchten?), Dann müssen Sie sicherstellen, dass die Zeichenfolge die Verwendung der Referenz überlebt. Sie können das tun, indem Sie den Konstruktorparameter in eine Referenz ändern.

Bike(std::string& name) : m_name(name) {} 

Obwohl ich glaube, es wäre besser, zu überdenken, ob Sie einen Verweis in erster Linie der Speicherung werden sollen. Es scheint hier nicht viel Sinn zu machen.