Frage

Ich habe einige Fragen auf einen Verweis auf eine lokale Variable aus einer Funktion zurückkehrt:

class A {
public:
    A(int xx)
    : x(xx)
    {
        printf("A::A()\n");
    }
};

const A& getA1()
{
    A a(5);
    return a;
}

A& getA2()
{
    A a(5);
    return a;
}

A getA3()
{
    A a(5);
    return a;
}

int main()
{
    const A& newA1 = getA1(); //1
    A& newA2 = getA2(); //2
    A& newA3 = getA3(); //3
}

Meine Fragen sind =>

  1. Ist die Umsetzung der getA1() richtig? Ich glaube, es ist falsch, da es die Adresse einer lokalen Variablen oder nur vorübergehend zurück.

  2. Welche der Aussagen in main (1,2,3) wird zu undefinierten Verhalten führen?

  3. In const A& newA1 = getA1(); hat die Standard-Garantie, dass eine vorübergehende durch eine konstante Referenz gebunden werden erst die Referenz zerstört geht out of scope?

War es hilfreich?

Lösung

  

1. Ist getA1() Implementierung korrekt? Ich glaube, es ist falsch, da es Adresse einer lokalen Variablen oder vorübergehend zurückkehrt.

Die einzige Version von getAx() der richtigen in Ihrem Programm ist getA3(). Beide der anderen haben nicht definiertes Verhalten, egal wie man sie später verwenden.

  

2. Welche der Aussagen in main (1,2,3) zu undefinierten Verhalten führen wird?

In gewisser Hinsicht keinen von ihnen. Für 1 und 2 ist das nicht definiertes Verhalten als Folge des Körpers der Funktionen. Für die letzte Zeile sollte, newA3 einen Compiler-Fehler, wie Sie keine temporäre auf eine nicht konstante Referenz binden kann.

  

3. In const A& newA1 = getA1(); tut Standard garantiert, dass temporäre Bindung durch eine const   Bezug wird nicht zerstört werden, bis die Referenz außerhalb des Bereichs geht?

Nein. Im Folgenden ist ein Beispiel dafür:

A const & newConstA3 = getA3 ();

Hier gibt getA3() eine temporäre und die Lebensdauer dieser temporären wird nun auf das Objekt newConstA3 gebunden. Mit anderen Worten wird die temporäre bis newConstA3 existieren geht out of scope.

Andere Tipps

Q1:. Ja, das ist ein Problem, siehe Antwort auf Q2

Q2: 1 und 2 sind nicht definiert, da sie auf lokale Variablen auf dem Stapel von getA1 und getA2 beziehen. Diese Variablen gehen aus Umfang und sind nicht mehr verfügbar und schlimmer kann überschrieben werden, wenn der Stapel ständig ändert. getA3 arbeitet, da eine Kopie des Rückgabewertes wird an den Aufrufer erstellt und zurückgegeben.

Q3: keine solche Garantie besteht Antwort auf Q2 zu sehen

.

Ich denke, das Hauptproblem ist, dass Sie nicht Provisorien zurückkehren, werden überhaupt, sollten Sie

return A(5);

statt

A a(5);
return a;

Ansonsten Sie zurückgeben lokale Variable Adresse, nicht nur vorübergehend. Und das nur vorübergehend konstante Referenz funktioniert nur für Provisorien.

Ich denke, die hier erklärt: vorübergehend const Referenz

Wenn Sie dies auf VC6 kompilieren Sie diese Warnung

****** Compilerwarnung (Stufe 1) C4172 Rückkehr-Adresse der lokalen Variablen oder vorübergehender Eine Funktion gibt die Adresse eines lokalen Variablen oder temporären Objekts. Lokale Variablen und temporäre Objekte werden zerstört, wenn eine Funktion zurückkehrt, so dass die Adresse zurückgegeben wird, ist nicht gültig. ******

Während für dieses Problem Prüfung fand ich interessante Sache (gegebener Code arbeitet in VC6):

 class MyClass
{
 public:
 MyClass()
 {
  objID=++cntr;
 }
MyClass& myFunc()
{
    MyClass obj;
    return obj;
}
 int objID;
 static int cntr;
};

int MyClass::cntr;

main()
{
 MyClass tseadf;
 cout<<(tseadf.myFunc()).objID<<endl;

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top