Nur eine kleine Frage zu shared_ptr
.
Ist es eine gute Praxis, shared_ptr
auf ein Array zu zeigen? Beispielsweise,
shared_ptr<int> sp(new int[10]);
Wenn nicht, warum dann nicht? Ein Grund, den ich bereits kenne, ist, dass man das nicht erhöhen / verringern kann shared_ptr
. Daher kann es nicht wie ein normaler Zeiger auf ein Array verwendet werden.
c++
c++11
shared-ptr
tshah06
quelle
quelle
std::vector
. Sie müssen vorsichtig sein, um das Array mithilfe von Referenzen weiterzugeben, damit Sie keine Kopien davon erstellen. Die Syntax für den Zugriff auf Daten ist sauberer als shared_ptr, und die Größenänderung ist sehr, sehr einfach. Und Sie erhalten alle STL-Güte, falls Sie es jemals wollen.std::array
. Es ist fast das gleiche wie ein Raw-Array, jedoch mit der richtigen Semantik für die meisten Bibliothekskomponenten. Insbesondere Objekte dieser Art werden mitdelete
nicht zerstörtdelete[]
. Im Gegensatzvector
dazu werden die Daten direkt im Objekt gespeichert, sodass Sie keine zusätzliche Zuordnung erhalten.Antworten:
Mit C ++ 17 ,
shared_ptr
kann verwendet werden , um eine dynamisch zugewiesenen Array zu verwalten. Dasshared_ptr
Vorlagenargument muss in diesem FallT[N]
oder seinT[]
. Also kannst du schreibenAb n4659 [util.smartptr.shared.const]
Um dies zu unterstützen, ist der Elementtyp
element_type
jetzt definiert alsAuf Array-Elemente kann mit zugegriffen werden
operator[]
Vor dem C ++ 17 ,
shared_ptr
konnte nicht dynamisch zugewiesenen Arrays verwalten verwendet werden. Standardmäßigshared_ptr
wirddelete
das verwaltete Objekt aufgerufen , wenn keine Verweise mehr darauf vorhanden sind. Wenn Sie jedoch mit zuweisen, müssennew[]
Sie die Ressource aufrufendelete[]
und nichtdelete
, um sie freizugeben.Zur korrekten Verwendung
shared_ptr
mit einem Array müssen Sie einen benutzerdefinierten Löscher angeben.Erstellen Sie den shared_ptr wie folgt:
shared_ptr
Wird jetzt korrekt aufgerufen,delete[]
wenn das verwaltete Objekt zerstört wird.Der oben angegebene benutzerdefinierte Löscher kann durch ersetzt werden
die
std::default_delete
teilweise Spezialisierung für Array-Typenein Lambda-Ausdruck
Außerdem
unique_ptr
ist a für diese Aufgabe besser geeignet , es sei denn, Sie benötigen tatsächlich eine gemeinsame Verwaltung des verwalteten Objekts , da es eine teilweise Spezialisierung für Array-Typen aufweist.Änderungen, die durch die C ++ - Erweiterungen für Bibliotheksgrundlagen eingeführt wurden
Eine weitere Alternative vor C ++ 17 zu den oben aufgeführten wurde von der Library Fundamentals Technical Specification bereitgestellt , die erweitert wurde
shared_ptr
, damit sie für den Fall, dass sie ein Array von Objekten besitzt, sofort einsatzbereit ist. Der aktuelle Entwurf dershared_ptr
für diesen TS geplanten Änderungen ist in N4082 zu finden . Auf diese Änderungen kann über denstd::experimental
Namespace zugegriffen und in die<experimental/memory>
Kopfzeile aufgenommen werden. Einige der relevanten Änderungen zur Unterstützungshared_ptr
von Arrays sind:- Die Definition des Elementtyps
element_type
ändert sich- Mitglied
operator[]
wird hinzugefügt- Im Gegensatz zur
unique_ptr
teilweisen Spezialisierung für Arrays sind beideshared_ptr<T[]>
undshared_ptr<T[N]>
gültig und führen dazu,delete[]
dass das verwaltete Array von Objekten aufgerufen wird.quelle
shared-array
.shared_ptr::get
gibt einen Zeiger auf das verwaltete Objekt zurück. So können Sie es alssp.get()[0] = 1; ... sp.get()[9] = 10;
std::shared_ptr<int> sp( new int[10], std::default_delete<int[]>() );
siehe auch en.cppreference.com/w/cpp/memory/default_deletestd::shared_ptr<std::array<int,N>>
sollte ausreichen.unique_ptr
bekommt diese Teilspezialisierung abershared_ptr
nicht?Eine möglicherweise einfachere Alternative, die Sie möglicherweise verwenden können, ist
shared_ptr<vector<int>>
.quelle
shared_ptr<array<int, 6>>
.