Ich habe eine Klasse entwickelt und bin auf diese Frage gestoßen. Überlege, dass ich folgende Klasse habe:
%Vor% Und folgende Klasse mit A
als Eigenschaft:
Und diese Funktion, die nach einem variablen Wert sucht und verschiedene Objekte in verschiedenen Fällen zurückgibt:
%Vor%Nun möchte ich diese Funktion wie folgt verwenden:
%Vor%Der Zweck dieser Situation ist:
Funktion foo
sollte zurückgeben (oder verschieben), ohne ein lokales Objekt mit Änderungen in p
zu kopieren, wenn das Argument true
ist, oder sollte die Eigenschaft der globalen Variablen temp
ohne Aufruf von Kopierkonstruktoren von A
( dh Rückgabewert von myList
) und auch nicht myList
von B
(es sollte nicht myList
von B
zerstören, also std::move
kann nicht verwendet werden), wenn das Argument false
ist.
Meine Frage ist:
Wie soll ich die Funktion foo
ändern, um den oberen Bedingungen zu folgen? Die aktuelle Implementierung von foo
funktioniert in true
case und verschiebt diese lokale Variable, aber für den Fall false
wird der Kopierkonstruktor für list2
aufgerufen. Eine andere Idee war, die Lebensdauer der lokalen Variablen irgendwie zu verlängern, aber das Hinzufügen von const-Referenz funktionierte nicht für mich. Aktuelle Ausgabe ist:
Die einfachste Lösung ist wahrscheinlich die Verwendung von std::shared_ptr
wie in Jarod42s Antwort. Aber wenn Sie Smart Pointer vermeiden wollen oder wenn Sie B
nicht ändern können, können Sie wahrscheinlich Ihre eigene Wrapper-Klasse erstellen, die möglicherweise ein A
besitzt oder nicht. std::optional
könnte dafür sehr praktisch sein:
Die Klasse enthält optional
, um das A
zu besitzen, falls erforderlich, und Sie können move-semantics verwenden, um sie zu verschieben. Die Klasse enthält auch einen Verweis (oder Zeiger), der entweder auf den enthaltenen Wert verweist oder auf ein anderes Objekt verweist .
Sie können dies von foo
:
Und der Aufrufer kann auf die enthaltene Referenz zugreifen:
%Vor% Wenn Sie keinen Zugriff auf std::optional
haben, gibt es boost::optional
oder Sie könnten std::unique_ptr
auf Kosten einer dynamischen Speicherzuweisung verwenden.
Ihre Funktion foo gibt eine Instanz von A zurück, keine Referenz (oder einen Zeiger), sodass Sie keinen Zugriff auf B.myList
Um diesen Zugang zu haben, sollten Sie entweder intelligente Zeiger (wie Jarod42) verwenden oder einfach nur solche Zeiger:
%Vor%Allerdings wird dieser spezielle Code nicht funktionieren. coz .getList () gibt const zurück, aber foo gibt einen nicht-konstanten Zeiger zurück (dies könnte, sollte aber nicht schmutzig sein, gehackt mit const_cast & lt ; & gt;).
Im Allgemeinen müssen Sie auswählen, was genau die Funktion foo zurückgeben soll:
Wenn Sie diese Entscheidung zur Laufzeit treffen müssen (zum Beispiel mit Ihrem bool-Parameter), dann sind die Zeiger (einfach oder intelligent - was auch immer) die einzige Option (vergessen Sie auch nicht, manuell zugewiesenen Speicher zu löschen).
Tags und Links c++ c++11 reference move object-lifetime