Initialisierung von shared_ptrT aus unique_ptrT []

8

[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

%Vor%

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?

    
jaggedSpire 28.05.2015, 01:53
quelle

1 Antwort

6

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

%Vor%

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.

    
Praetorian 28.05.2015, 02:25
quelle

Tags und Links