Wie die Zuweisung einer Adresse zu einem bestehenden Objekt zu einem smart-pointer?
#include <memory>
class bar{};
void foo(bar &object){
std::unique_ptr<bar> pointer = &object;
}
Will ich weisen Sie eine Adresse des Objekts, auf den Zeiger. Der obige code natürlich nicht kompilieren, da die Rechte Seite des zuweisungsoperators muss eine std::unique_ptr. Ich habe bereits versucht:
pointer = std::make_unique<bar>(object)
Aber es wirft viele Fehler während der Kompilierung. Wie kann ich das tun?
Update
Wie gesagt, in den Antworten - mithilfe der std::unique_ptr::reset
Methode führte zu undefiniertem Verhalten. Jetzt weiß ich, dass in solchen Fällen sollte ich verwenden, ein standard-Zeiger.
InformationsquelleAutor der Frage Tomasz Kasperczyk | 2015-02-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuchen std::unique_ptr::reset
Aber bewusst sein, dies wird nicht empfohlen,sollten Sie nicht erstellen Sie ein
unique_ptr
auf einen Verweis, wird an eine Funktion übergeben. Am Ende der Funktion, wennpointer
ist zerstört, es wird versuchen, zu zerstörenobject
als gut, und es nicht verfügbar sein wird außerhalb der Funktion aufrufen, was in einer access-memory " - Fehlermeldung.Beispiel: Dies kompiliert, aber gib runtime error.
Auf der anderen Seite möchten Sie vielleicht zu prüfen, mit shared_ptr dies kann Ihnen helfen, zu entscheiden: unique_ptr oder shared_ptr?.
InformationsquelleAutor der Antwort Raydel Miranda
Können Sie erst zuordnen, andere
unique_ptr
oder dienullptr
. Wenn Sie darüber nachdenken, es macht auch Sinn (obwohlreset
lassen Sie tun, was Sie wollen, aber ich denke, das ist tatsächlich ein Fehler oder Mangel inunique_ptr
).Einen
unique_ptr
ist der alleinige Eigentümer des Spitzen-zu-Objekt. Wenn Sie den Bereich verlässt, wird es löschen Sie das Objekt.Dies bedeutet, dass die Funktion Waschbecken Semantik. Der Zeiger übergeben Sie (oder vielmehr das Spitze-zu-Objekt") konsumiert wird, das heißt, es "verschwindet" (Waschbecken) innerhalb der Funktion. Übergeben Sie ein Objekt über eine Referenz (auf ein Objekt welches nicht einmal unbedingt heap zugewiesen werden, bereiten Sie für eine überraschung, wenn Sie übergeben Sie ein Objekt mit automatischer Speicherung!) und plötzlich ist es Weg. Bang.
Waschbecken Semantik vermittelt werden sollten, richtig. Sie passieren soll, einem
unique_ptr
als Funktions-parameter. Unique-Zeiger dürfen nicht kopiert werden, so dass der Benutzer gezwungen, die Funktion zu verwendenstd::move
erstellen Bewusstsein von dem, was tatsächlich geschieht.Dass ein Objekt "verschwinden", ist eine böse überraschung, diese sollte nicht nur zufällig unabsichtlich.
InformationsquelleAutor der Antwort Damon
Könnten Sie nennen
std::unique_ptr::reset
:aber die eigentliche Frage ist: Ist das wirklich tun, was Sie erwarten, es zu tun? Wenn das Objekt nicht erstellt über
new
die oben genannten können sehr gefährlich sein. Gegeben, dass Sie noch nicht mehr Informationen, Sie könnte haben eine gültige use-case -, aber ohne diese Informationen scheint es, wie eine mögliche Quelle der Zukunft Schwierigkeiten. Was Sie effektiv tun, in Ihrem Beispiel ist, dass Sie verbrauchen das Objekt, D. H., nachdem die Funktion aufgerufen wurde, die Lebensdauer derunique_ptr
beendet und das Objekt gelöscht wurde. Wenn dies dokumentiert ist/löschen, um die Anrufer, könnte es OK sein - ansonsten ein Umdenken in der Gestaltung. Und selbst wenn dies vorgesehen ist design, es ist viel besser, eineunique_ptr
als argument für die Funktion selbst:Bedeutet dies zwei Dinge:
InformationsquelleAutor der Antwort Daniel Frey
Erlauben Sie mir, Sie zu enttäuschen, aber Sie nicht. Hast du da eine Referenz, die können zeigen Sie auf einen dynamisch zugewiesenen Objekt-oder stack-Objekt zugeordnet, oder, vielleicht, ein Objekt in einem dynamisch reservierten Arrays, die nicht individuell vergeben.
Möchten Sie seine Adresse in einer Klasse, wird automatisch rufen Sie löschen auf diese Adresse. Die ungültig ist für die meisten Situationen, die oben präsentiert. Das ist falsch. So übergeben Sie eine Referenz und setzen Sie die Adresse der Referenz in ein smart pointer soll nie geschehen, niemals. Vor allem nicht mit reset().
Am meisten, was möchten Sie vielleicht zu tun ist, initialisieren Sie die smart pointer mit der neu zugewiesenen Objekt, zum Beispiel:
Nicht schon mal die Adresse einer Referenz. Je. Ohne Grund. Es ist moralisch falsch. Es ist nicht, weil die Verwendung von Referenz-Adressen ist unzulässig, denn es kann gültig sein, verwenden; es ist, weil zwei Monate später die neue Kollegin benutzen möchten, die Adresse mit einem smart-pointer, weil das ist, wie (s)er habe gehört, dass es heutzutage praktiziert, und dann kommen, um Stack-Überlauf und gelesen, dass Sie sollten "reset" für die Zeiger. Das ist falsch, schmerzhaft falsch.
InformationsquelleAutor der Antwort Dorin Lazăr
Die Funktion, die Sie suchen, ist
reset()
. Hier ist ein Beispiel:Hier
pointer
ist einunique_ptr
. Aufrufreset()
zerstören wird das Vorherige Objekt verwaltetpointer
(wenn vorhanden) und machenobject
die aktuelle managed-object-vonpointer
.Oder, wenn Sie wollen
object
das verwaltete Objekt direkt beim initialisieren desunique_ptr
:Ein Wort der Warnung jedoch:
object
zugeordnet werden soll, mitnew
wenn du gehst, um es zu verwalten, indem Sie eineunique_ptr
weilunique_ptr
kann versuchen, Sie zu rufendelete
. Wenn es nicht erstellt wurde mitnew
nicht wickeln Sie es in einunique_ptr
das ist nicht das, was Sie sind für.InformationsquelleAutor der Antwort emlai
Was ich sehen kann ist, das Sie haben wollen unique_ptr-Objekt, das die Punkte auf ein Objekt im Speicher,aber Sie nicht wollen, zu übertragen das Eigentum an den Speicher.
Müssen Sie zum erstellen von custom deleter für das Objekt, die eigentlich nicht löschen Sie das Objekt:
unique_ptr ist eine Vorlage, wo das zweite argument ist die deleter des Objekts. Standardmäßig ist es default_deleter, aber man kann es austauschen mit diesem fake:
post Bearbeiten:
Dasselbe können Sie tun, mit shared_ptr, aber da shared_ptr gewirkt werden kann, zum anderen shared_ptr in vererbungsbaum des Objekts, der deleter wird nicht gespeichert-in-class-template-argument, aber es ist Vergangenheit, die als Instanz-member. Dies macht es leichter zu bedienen IMO:
Können Sie einige benutzerdefinierte Freigabe von Ressourcen:
InformationsquelleAutor der Antwort Milan