HOWTO · C++

So geben Sie eine Zeichenkette aus einer Funktion in C++ zurück

Dieser Artikel zeigt, wie man eine Zeichenkette aus einer Funktion in C++ zurückgibt

Auf dieser Seite

Geben Sie in einer gewöhnlichen C++-Funktion ein std::string als Wert zurück. So erhält der Aufrufer eine unabhängige Zeichenkette, und C++ kann, sofern möglich, die Rückgabewertoptimierung anwenden. Verwenden Sie eine Referenz nur, wenn Sie ein vorhandenes Objekt zurückgeben, dessen Lebensdauer anderweitig verwaltet wird. Einen Zeiger oder eine C-Zeichenkette sollten Sie nur verwenden, wenn eine Schnittstelle dies ausdrücklich verlangt. Die folgenden Beispiele setzen C++11 oder höher voraus.

Eine Zeichenkette als Wert zurückgeben

Die Rückgabe als Wert ist die klarste Standardlösung, wenn eine Funktion eine Zeichenkette erstellt oder umwandelt. Der Aufrufer erhält einen eigenen Zeichenkettenwert, den er unabhängig speichern oder ändern kann. Die Rückgabe einer benannten lokalen Variablen ist normalerweise effizient: Der Compiler kann das Ergebnis durch die benannte Rückgabewertoptimierung direkt am Zielort des Aufrufers konstruieren. Falls diese Optimierung nicht greift, kann std::string verschoben werden. Für keine dieser Möglichkeiten muss std::move zur Rückgabeanweisung hinzugefügt werden.

Führen Sie dieses Beispiel aus:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

#include <iostream>
#include <string>

std::string makeGreeting() {
    std::string result = "Hello, C++!";
    return result;
}

int main() {
    std::string greeting = makeGreeting();
    std::cout << greeting << '\n';
}

Der Rückgabetyp der Funktion ist std::string, und return result; gibt den lokalen Wert zurück. Die lokale Variable wird beim Beenden der Funktion zerstört, doch die zurückgegebene Zeichenkette bleibt dem Aufrufer erhalten. Einen Wert zurückzugeben ist gewöhnlich einfacher und sicherer, als den Besitz einer dynamisch reservierten Zeichenkette separat zu regeln.

Eine Referenz auf eine vorhandene Zeichenkette zurückgeben

Bei der Rückgabe einer Referenz wird ein bereits vorhandenes Objekt referenziert; es entsteht keine neue Zeichenkette. Das kann nützlich sein, wenn eine Funktion eine Zeichenkette auswählt oder zugänglich macht, die einem länger lebenden Objekt gehört. Der Aufrufer sieht dasselbe Objekt. Änderungen über eine nicht konstante Referenz wirken sich daher auf das Original aus. Verwenden Sie const std::string&, wenn Aufrufer die Zeichenkette lesen, aber nicht ändern sollen.

Das referenzierte Objekt muss bei jeder Verwendung der zurückgegebenen Referenz noch existieren. Geben Sie niemals eine Referenz auf eine lokale Variable zurück: Diese wird beim Verlassen der Funktion zerstört, sodass der Aufrufer eine ungültige Referenz erhält. Eine Referenz auf einen Funktionsparameter kann nur dann sicher zurückgegeben werden, wenn der Aufrufer das Argument am Leben hält, wie in diesem Beispiel:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

#include <iostream>
#include <string>

const std::string& sameString(const std::string& value) {
    return value;
}

int main() {
    std::string original = "Existing string";
    const std::string& alias = sameString(original);
    std::cout << alias << '\n';
}

Eine Zeichenkette über einen Zeiger zurückgeben

Die Rückgabe eines Zeigers kann einen optionalen Zugriff ausdrücken oder einer vorhandenen Schnittstelle entsprechen. Dabei werden Lebensdauer und Besitz jedoch Teil des Vertrags. Geben Sie die Adresse einer vorhandenen Zeichenkette nur dann zurück, wenn diese länger als jede Verwendung des Zeigers existiert. Dokumentieren Sie, wem das Objekt gehört und ob der Zeiger null sein darf.

Reservieren Sie keine std::string mit new, nur um sie zurückzugeben. Der Aufrufer muss dann daran denken, sie mit delete freizugeben; außerdem wird der Umgang mit vorzeitigen Rückgaben und Fehlern schwieriger. Geben Sie eine neu erstellte Zeichenkette als Wert zurück. Das folgende Beispiel verweist auf ein vorhandenes Objekt und lässt es während der Verwendung des Zeigers am Leben:

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

#include <iostream>
#include <string>

const std::string* findGreeting(const std::string& value) {
    return &value;
}

int main() {
    std::string greeting = "Hello through a pointer";
    const std::string* result = findGreeting(greeting);
    if (result != nullptr) {
        std::cout << *result << '\n';
    }
}

Die Funktion übernimmt nicht den Besitz von value. Der Aufrufer darf den zurückgegebenen Zeiger nicht behalten, nachdem die referenzierte Zeichenkette zerstört wurde.

std::move nur verwenden, wenn es hilft

std::move ist eine Umwandlung, die eine Verschiebeoperation ermöglicht; sie verschiebt selbst keine Daten. In einer Rückgabeanweisung ist return std::move(local); normalerweise unnötig. Dadurch kann die benannte Rückgabewertoptimierung verhindert werden, sodass möglicherweise statt der direkten Konstruktion eine Verschiebung stattfindet. Verwenden Sie für ein lokales Ergebnis bevorzugt return local; und überlassen Sie es der Sprache und dem Compiler, die mögliche Optimierung auszuwählen.

Explizite Verschiebungen sind sinnvoll, wenn ein Objekt übertragen werden soll, für das keine automatische Verschiebung infrage kommt, etwa ein Element, das aus einem länger lebenden Objekt heraus verschoben werden muss. Dadurch ändert sich das ursprüngliche Objekt. Verwenden Sie die Verschiebung daher nur, wenn dessen bisheriger Zustand nicht mehr benötigt wird. Fügen Sie std::move nicht allein hinzu, damit eine Rückgabe schneller wirkt.

Eine C-Zeichenkette mit char* zurückgeben

Eine C-Zeichenkette ist eine nullterminierte Zeichenfolge und kein std::string. Wenn eine API einen Zeichenzeiger verlangt und das Ergebnis aus festem Text besteht, geben Sie einen const char* zurück, der auf ein Zeichenkettenliteral zeigt. Zeichenkettenliterale haben eine statische Speicherdauer; der Zeiger bleibt daher während des gesamten Programms gültig. const char* bedeutet hier, dass der Zeiger auf konstante Zeichen zeigt: Die Zeichen lassen sich über diesen Zeiger nicht ändern, der Zeiger selbst ist jedoch nicht konstant und kann neu zugewiesen werden. Davon zu unterscheiden ist char* const: ein konstanter Zeiger auf veränderbare Zeichen. Das Zeichenkettenliteral darf nicht verändert werden.

Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.

#include <iostream>

const char* greeting() {
    return "Hello from C-style text";
}

int main() {
    std::cout << greeting() << '\n';
}

Geben Sie weder einen Zeiger auf ein lokales Zeichenarray zurück, das beim Verlassen der Funktion nicht mehr existiert, noch einen Zeiger in ein lokales std::string. Das Ergebnis von c_str() ist an die Lebensdauer des std::string-Objekts gebunden und kann durch Änderungen an dieser Zeichenkette ungültig werden. Wenn der Aufrufer ein unabhängig besessenes und veränderbares Ergebnis benötigt, geben Sie stattdessen std::string zurück.