[Folge zu dieser Frage ]
Ich habe mich in letzter Zeit ein wenig mit intelligenten Zeigern für c-artige Arrays beschäftigt. Letztendlich habe ich die empfohlene Sache gemacht und stattdessen intelligente Zeiger auf Vektoren verwendet, aber in diesem Zeitraum habe ich ein paar Ratschläge erhalten: Verwende kein shared_ptr<T>
-Objekt, um ein Array zu verwalten, das ursprünglich mit make_unique<T[]>
erstellt wurde, weil es gewonnen hat Nennen Sie nicht delete[]
, sondern delete
.
Das erschien mir nicht logisch, und ich überprüfte sowohl Coliru als auch den Standard
>Dieser Code:
%Vor%erzeugt diese Ausgabe:
%Vor% Dies scheint darauf hinzuweisen, dass der Deleter von unique_ptr<T[]>
wie erwartet an das shared_ptr<T>
übergeben wird.
Aus dem C ++ 14 Standard § 20.8.2.2.1 pg. 571 von doc, 585 von pdf
Vorlage shared_ptr (unique_ptr & amp; & amp; r);
Anmerkung : Dieser Konstruktor darf nicht an der Überladungsauflösung teilnehmen, es sei denn unique_ptr :: pointer ist in T * konvertierbar.
Effekte : Entspricht shared_ptr (r.release (), r.get_deleter ()) wenn D kein Referenztyp ist, andernfalls shared_ptr (r.release (), ref (r.get_deleter ())).
Ausnahmesicherheit : Wenn eine Ausnahme ausgelöst wird, hat der Konstruktor keine Wirkung.
Wenn ich das richtig lese, bedeutet das, dass sich ein shared_ptr
-Objekt sowohl vom Zeiger als auch vom Deleter eines unique_ptr
konstruiert. Außerdem verstehe ich (von der Antwort auf die ursprüngliche Frage), dass der ::pointer
-Typ von unique_ptr<T[]>
T*
ist, der in shared_ptr<T>::pointer
s T*
konvertiert werden kann. Also sollte der Deleter direkt vom Objekt unique_ptr
kopiert werden, richtig?
Hat mein Test nur funktioniert, weil er nicht wirklich der Funktion von std::make_shared<T[]>
entspricht, oder ist die Syntax
eine gute, ausnahmesichere (und sauberere) Alternative zu
%Vor% und seiner Art, wenn ich Boosts Shared Array nicht verwenden kann und möchten vermeiden, dass entweder der Header vector
oder der array
mit meinem Code eingeschlossen wird?
Ja, Ihr Beispiel ist aus genau den Gründen gültig, die Sie angegeben haben. unique_ptr::pointer
ist int *
, und Sie versuchen, die Eigentumsrechte an einem shared_ptr<int>
zu übergeben, sodass der konvertierende Konstruktor, den Sie aufgelistet haben, an der Überladungsauflösung teilnimmt und eine Kopie des Deleters erstellt ( std::default_delete<int[]>
) weil es kein Referenztyp ist.
Das Folgende ist also gültig und ruft delete[]
auf, wenn die shared_ptr
Referenzzählung auf Null geht
Eine andere Möglichkeit, dies zu schreiben, außer dem Lambda, das Sie gezeigt haben, ist
%Vor% was dazu führt, dass mySharedArray
den gleichen Deleter wie die vorherige Zeile erhält.
Tags und Links c++ c++14 unique-ptr shared-ptr