Frage

Ich beginne wieder mit c ++ und über den Umfang der Variablen gedacht habe. Wenn ich eine Variable in einer Funktion, und dann will ich wieder diese Variable die Variable nicht „tot“ sein, wenn es zurückgegeben wird, weil der Umfang es in beendeter wurde?

Ich habe versucht, dies mit einer Funktion einen String zurückkehrt und es hat funktioniert. Kann das jemand erklären? Oder zumindest zeigen Sie mir an einen Ort, der mir dies erklären kann, bitte.

Danke

War es hilfreich?

Lösung

  

Wenn die Funktion beendet wird, die   folgende Schritte geschehen:

     
      
  • Der Rückgabewert der Funktion ist   in den Platzhalter kopiert, das war   setzt auf dem Stapel für diesen Zweck.

  •   
  • Alles nach dem Stapelrahmen   Zeiger wird aufgetaucht wird. Dies zerstört   alle lokalen Variablen und Argumente.

  •   
  • Der Rückgabewert wird die knallte aus   Stapel und wird als der Wert zugewiesen   die Funktion. Wenn der Wert des   Funktion ist nicht auf irgendetwas zugeordnet,   keine Zuordnung erfolgt, und die   Wert verloren.

  •   
  • Die Adresse des nächsten Befehls   auszuführen, wird von dem Stapel genommene,   und die CPU nimmt die Ausführung an   diese Anweisung.

  •   

Stack und dem Heap

Andere Tipps

Wenn Sie einen Wert zurückgeben, wird eine Kopie gemacht. Der Umfang der lokalen Variablen endet, sondern eine Kopie gemacht wird, und kehrte in die aufrufende Funktion. Beispiel:

int funcB() {
  int j = 12;
  return j;
}

void A() {
  int i;
  i = funcB();
}

Der Wert von j (12) kopiert und wieder in i, so dass ich den Wert von 12 erhalten.

Es hängt wirklich davon ab, welche Art von Variablen, die Sie zurückkommen. Wenn Sie ein primitiven dann zurück durch Kopie zurückgegeben wird, nicht durch Bezugnahme so dass der Wert an die Spitze des Stapels kopiert (oder häufiger in ein Register gestellt), wo die aufgerufene Funktion es bekommen kann. Wenn Sie ein Objekt oder Speicher auf dem Heap reservieren und einen Zeiger zurückgeben dann stirbt es nicht, weil es auf dem Heap ist, nicht der Stapel. Wenn Sie etwas auf dem Stapel zuweisen, aber, und senden Sie es, dass eine schlechte Sache wäre. Zum Beispiel eine diese wäre sehr schlecht:

int *myBadAddingFunction(int a, int b)
{
    int result;

    result = a + b;
    return &result; // this is very bad and the result is undefined
}

char *myOtherBadFunction()
{
    char myString[256];

    strcpy(myString, "This is my string!");
    return myString; // also allocated on the stack, also bad
}

Nur für ein bisschen mehr von einer Speicher-Modell orientierte Erklärung: Wenn eine Funktion aufgerufen wird, ein temporärer Raum für die Funktion gemacht wird seine lokalen Variablen zu setzen, eine so genannten Rahmen . Wenn die Funktion (Rufenen) seinen Wert zurückgibt, den Rückgabewert im Rahmen der Funktion setzt, die sie aufgerufen (Anrufer), und dann wird der Angerufene Rahmen zerstört.

Der „Rahmen wird zerstört“ Teil ist, warum Sie keine Zeiger oder Verweise auf lokale Variablen von Funktionen zurückgeben kann. Ein Zeiger ist effektiv eine Speicherstelle, so dass die Speicherstelle einer lokalen Variablen zurückzukehr (per Definition: eine Variable innerhalb des Rahmens) wird, sobald der fehlerhafte Rahmen zerstört wird. Da der Angerufene Rahmen sobald es gibt seinen Wert zurück, jeden Zeiger oder eine Referenz auf eine lokale Variable ist sofort falsch zerstört.

Die lokale Variable wird auf den Rückgabewert kopiert. Kopierkonstruktoren sind für nicht-triviale Klassen genannt.

Wenn Sie einen Zeiger oder eine Referenz auf eine lokale Variable zurückkehren Sie Schwierigkeiten haben, --- wie Sie Ihre Intuition vorgeschlagen.

Dies ist abhängig von der Art der Rücksendung. Wenn Sie mit dem Wert zurückkehren, wird eine neue Kopie der Variablen an den Anrufer zurückgeführt. Ich dünnt Fall brauchen Sie nicht über Objektlebensdauer zu kümmern, aber Sie können über die Kosten des Kopierens Objekte kümmern müssen (aber bitte nicht vorzeitig optimze - Korrektheit ist viel wichtiger):

std::string someFunc( std::string& const s)
{
    return s + "copy";
}

Wenn die Funktion eine Referenz zurückgibt, dann müssen Sie vorsichtig sein, was Sie zurückkehren, weil es Lebensdauer Bedürfnisse ist über die Funktion der Lebensdauer zu verlängern und der Anrufer wird notwendigerweise nicht in der Lage sein todelete es wenn Sie mit new zu erstellen Sie das Objekt:

std::string& someFunc2( std::string const& s)
{
    return s + "reference to a copy";   // this is bad - the temp object created will 
                                        //  be destroyed after the expression the 
                                        //  function call is in finishes.
                                        //  Some, but not all, compilers will warn 
                                        //  about this.
}

Natürlich Rückkehr Zeiger werden ähnliche Lebensdauer Überlegungen haben.

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