Verlängert ein const-Referenzklassenmitglied die Lebensdauer einer temporären?

Verlängert ein const-Referenzklassenmitglied die Lebensdauer einer temporären?

Nur lokal const Referenzen verlängern die Lebensdauer.

Der Standard spezifiziert ein solches Verhalten in §8.5.3/5, [dcl.init.ref], dem Abschnitt über Initialisierer von Referenzdeklarationen. Die Referenz in Ihrem Beispiel ist an das Argument n des Konstruktors gebunden , und wird ungültig, wenn das Objekt n zwangsläufig außerhalb des Gültigkeitsbereichs liegt.

Die Lebensdauererweiterung ist nicht transitiv durch ein Funktionsargument. §12.2/5 [class.temporary]:


So lässt sich am einfachsten erklären, was passiert ist:

In main() haben Sie einen String erstellt und an den Konstruktor übergeben. Diese Zeichenfolgeninstanz existierte nur innerhalb des Konstruktors. Innerhalb des Konstruktors haben Sie das Mitglied so zugewiesen, dass es direkt auf diese Instanz zeigt. Als der Geltungsbereich den Konstruktor verließ, wurde die Zeichenfolgeninstanz zerstört, und das Mitglied zeigte dann auf ein Zeichenfolgenobjekt, das nicht mehr existierte. Wenn Sandbox.member auf eine Referenz außerhalb seines Bereichs zeigt, werden diese externen Instanzen nicht im Bereich bleiben.

Wenn Sie Ihr Programm so reparieren möchten, dass es das gewünschte Verhalten anzeigt, nehmen Sie die folgenden Änderungen vor:

int main()
{
    string temp = string("four");    
    Sandbox sandbox(temp);
    cout << sandbox.member << endl;
    return 0;
}

Jetzt wird temp am Ende von main() statt am Ende des Konstruktors aus dem Gültigkeitsbereich übergeben. Dies ist jedoch eine schlechte Praxis. Ihre Mitgliedsvariable sollte niemals ein Verweis auf eine Variable sein, die außerhalb der Instanz existiert. In der Praxis weiß man nie, wann diese Variable den Geltungsbereich verlässt.

Was ich empfehle, ist, Sandbox.member als const string member; zu definieren Dadurch werden die Daten des temporären Parameters in die Mitgliedsvariable kopiert, anstatt die Mitgliedsvariable selbst als temporären Parameter zuzuweisen.


Technisch gesehen muss dieses Programm nichts auf die Standardausgabe ausgeben (was zunächst ein gepufferter Stream ist).

  • Die cout << "The answer is: " Bit wird "The answer is: " ausgeben in den Puffer von stdout.

  • Dann die << sandbox.member bit liefert die baumelnde Referenz in operator << (ostream &, const std::string &) , was undefiniertes Verhalten aufruft .

Aus diesem Grund passiert garantiert nichts. Das Programm funktioniert möglicherweise scheinbar einwandfrei oder stürzt ab, ohne stdout zu leeren – was bedeutet, dass der Text „The answer is:“ nicht auf Ihrem Bildschirm erscheinen würde.