Bitte beachten Sie diesen Code. Ich habe diese Art von Code mehrmals gesehen. words
ist ein lokaler Vektor. Wie ist es möglich, es von einer Funktion zurückzugeben?
Können wir garantieren, dass es nicht stirbt?
std::vector<std::string> read_file(const std::string& path)
{
std::ifstream file("E:\\names.txt");
if (!file.is_open())
{
std::cerr << "Unable to open file" << "\n";
std::exit(-1);
}
std::vector<string> words;//this vector will be returned
std::string token;
while (std::getline(file, token, ','))
{
words.push_back(token);
}
return words;
}
std::vector<std::string>&
Antworten:
Solange keine Referenz zurückgegeben wird, ist dies vollkommen in Ordnung.
words
wird in die Variable verschoben, die das Ergebnis empfängt.Die lokale Variable verlässt den Gültigkeitsbereich. nachdem es verschoben (oder kopiert) wurde.
quelle
Vor C ++ 11:
Die Funktion gibt nicht die lokale Variable zurück, sondern eine Kopie davon. Ihr Compiler führt jedoch möglicherweise eine Optimierung durch, bei der keine tatsächliche Kopieraktion ausgeführt wird.
Weitere Informationen finden Sie in dieser Frage und Antwort .
C ++ 11:
Die Funktion verschiebt den Wert. Siehe diese Antwort für weitere Details.
quelle
Ich denke, Sie beziehen sich auf das Problem in C (und C ++), dass das Zurückgeben eines Arrays von einer Funktion nicht zulässig ist (oder zumindest nicht wie erwartet funktioniert) - dies liegt daran, dass das Array zurückgegeben wird (wenn Sie es einschreiben) die einfache Form) gibt einen Zeiger auf das tatsächliche Array auf dem Stapel zurück, der dann sofort entfernt wird, wenn die Funktion zurückkehrt.
In diesem Fall funktioniert es jedoch, da
std::vector
es sich um eine Klasse handelt und Klassen wie Strukturen in den Aufruferkontext kopiert werden können (und werden). [Tatsächlich optimieren die meisten Compiler diesen speziellen Kopiertyp mithilfe der sogenannten "Rückgabewertoptimierung", die speziell eingeführt wurde, um das Kopieren großer Objekte zu vermeiden, wenn sie von einer Funktion zurückgegeben werden. Dies ist jedoch eine Optimierung und aus Sicht des Programmierers auch verhalten sich so, als ob der Zuweisungskonstruktor für das Objekt aufgerufen wurde]Solange Sie keinen Zeiger oder Verweis auf etwas zurückgeben, das sich innerhalb der zurückgegebenen Funktion befindet, ist alles in Ordnung.
quelle
Um das Verhalten gut zu verstehen, können Sie diesen Code ausführen:
Die Ausgabe ist die folgende:
Beachten Sie, dass dieses Beispiel im C ++ 03-Kontext bereitgestellt wurde und für C ++> = 11 verbessert werden kann
quelle
Ich bin nicht einverstanden und empfehle nicht, Folgendes zurückzugeben
vector
:Das geht viel schneller:
Ich habe in Visual Studio 2017 mit den folgenden Ergebnissen im Release-Modus getestet:
8.01 MOPs nach Referenz
5.09 MOPs, die den Vektor zurückgeben
Im Debug-Modus sind die Dinge viel schlimmer:
0,053 MOPS als Referenz
0,034 MOPs als Rückgabevektor
quelle
Dies ist eigentlich ein Designfehler. Sie sollten keinen Rückgabewert für etwas verwenden, das kein Grundelement für etwas ist, das nicht relativ trivial ist.
Die ideale Lösung sollte durch einen Rückgabeparameter mit einer Entscheidung über Referenz / Zeiger und der richtigen Verwendung einer "Konstante \ 'y \' ness" als Deskriptor implementiert werden.
Darüber hinaus sollten Sie sich darüber im Klaren sein, dass die Beschriftung eines Arrays in C und C ++ effektiv ein Zeiger ist und das Abonnement effektiv ein Offset- oder Additionssymbol ist.
Die Bezeichnung oder ptr array_ptr === Array-Bezeichnung, die foo [offset] zurückgibt, sagt also wirklich return-Element an der Speicherzeigerposition foo + offset vom Typ return type.
quelle