Wie gehen deleter zu make_shared?
Seit C++11, da von mehreren Gründen, tendieren Entwickler dazu, den Einsatz von smart-pointer-Klassen für die dynamische Lebenszeit von Objekten. Und mit diesen neuen smart-pointer-Klassen, - standards, auch empfehlen nicht die Verwendung von Operatoren wie new
statt, die Sie vorschlagen, zu verwenden make_shared
oder make_unique
zu vermeiden, dass einige Fehler anfällig.
Wenn wir wie die Verwendung einer smart-pointer-Klasse, wie shared_ptr
können wir konstruieren ein wie,
shared_ptr<int> p(new int(12));
Auch wir gerne weitergeben möchte einen custom deleter smart-pointer-Klassen,
shared_ptr<int> p(new int(12), deleter);
Auf der anderen Seite, wenn wir wie zu verwenden make_shared
zu reservieren, für die ex. int
anstelle der Verwendung new
und shared_ptr
Konstruktor, wie auf den ersten Ausdruck, den wir verwenden können,
auto ip = make_shared<int>(12);
Aber was ist, wenn wir auch einen custom deleter zu make_shared
, gibt es eine richtige Weise, das zu tun? Scheint wie Compiler, zumindest gcc, gibt Fehler zu,
auto ip = make_shared<int>(12, deleter);
- Schreiben Sie Ihre eigene
make_shared()
, die dies unterstützt, ist es machbar.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie andere gesagt haben,
make_shared
kann nicht verwendet werden, mit einem custom deleter. Aber ich will erklären, warum.Benutzerdefinierte deleters existieren, weil Sie zugeordnet den Zeiger auf eine Besondere Art und Weise, und deshalb müssen Sie in der Lage sein, um deallocate es in eine entsprechend Besondere Art und Weise. Gut,
make_shared
weist der Zeiger mitnew
. Objekte zugewiesen mitnew
werden sollte, aufgehoben mitdelete
. Die standard-deleter pflichtbewusst tut.Kurz gesagt, wenn Sie Leben können mit den default-Zuweisung Verhalten, Sie Leben können mit den Standard - Freigabe Verhalten zu. Und wenn Sie nicht Leben können mit der Standard-Zuweisung Verhalten, sollten Sie
allocate_shared
, die mit der vorgesehenen Zuweisung sowohl allocate und deallocate der Lagerung.Auch
make_shared
darf (und fast sicher) den Speicher fürT
und der Steuerblock für die shared_ptr innerhalb der gleichen Zuweisung. Dies ist etwas, dass Ihr deleter nicht wirklich auskennen, oder befassen sich mit. In der Erwägung, dassallocate_shared
ist in der Lage Handhabung, da die Zuweisung die Sie tun können, - Allokation und-Freigabe Pflichten.shared_ptr
noch nicht unbedingt "zugewiesen" an alle. Sie möchten möglicherweise verwenden Siefclose
zum schließen einer DATEI* zum Beispiel. Mitallocate_shared
ermöglicht Ihnen die Steuerung der Speicherzuweisung, aber nicht beliebige Ressourcen. Sie haben noch zu konstruieren und zu zerstören ein Objekt, nicht erhalten "Ressource" aus einer Funktion und frei, es mit einem anderen (deleter) - Funktion. Auch wenn lwg 2070 wird behoben das immer noch nicht erlauben, benutzerdefinierte deleters mit machen/allocate_shared.shared_ptr
.X
und Funktionenget()
undput(X*)
. Sie können diese mitshared_ptr<X>(get(), &put)
aber es gibt keinen Weg, ummake_shared
oderallocate_shared
denn beide hängen vonsizeof(X)
ist nicht bekannt.make_shared
oderallocate_shared
, da der primäre Zweck der beiden ist für Ihnen, um das Objekt zu erstellen.allocate_shared
ist eine unnötige Ablenkung. Der Punkt ist, dass make_shared erstellt das Objekt, so sollten Sie auch Vertrauen, dass Sie "uncreate" es.allocate_shared
ist, dass es in vielen Fällen verwendet werden, wo Sie wollen eine explizite deleter. Nicht unbedingt alle, aber viele.new
, könnte es sich um Speicher mitstd::allocator
(wie meine Implementierung hat), odermalloc
. Oder eine benutzerdefinierte Zuweisung, oder etwas anderes. Die Sie nicht kennen, und so Ihre deleter würde nicht wissen, was zu tun ist. make_shared erstellt das Objekt, irgendwie, so sollten Sie Vertrauen, dass Sie uncreate es.Als von der Dokumentation,
make_shared
akzeptiert eine Liste der Argumente, mit dem eine Instanz von T konstruiert werden.Auch die Dokumentation sagt, dass:
Weil das so ist, können Sie ableiten, dass Sie können nicht von einer benutzerdefinierten deleter.
Um das zu tun, müssen Sie erstellen die
shared_ptr
für sich selbst, durch die richtige Konstruktor.Als ein Beispiel eines Konstruktors aus der vorgeschlagenen Liste, die Sie verwenden können:
So, der code wird so etwas wie:
Statt:
Können Sie nicht.
make_shared<T>
leitet die bereitgestellten Argumente an den Konstruktor des TypsT
. Es ist für den einfachen Fall, wenn Sie wollen, dass die Standard-deleter.Es ist nicht spezifiziert, wie
make_shared
erhält der Speicher für das Objekt (es könnteoperator new
odermalloc
oder irgendeine Art von Zuweisung), so gibt es keine Möglichkeit einen custom deleter konnte wissen, wie das richtige zu tun.make_shared
erstellt das Objekt, so haben Sie auch verlassen sich auf Sie, um das Objekt zu zerstören korrekt und die entsprechenden Aufräumen, was auch immer das ist.Ich glaube nicht, dass dies ist ein sehr realistisches Beispiel. Einen custom deleter ist in der Regel verwendet, wenn die Ressource erworben wurde, in eine Besondere Art und Weise. Wenn Sie gerade erstellt mit
new
wie dieses, dann warum brauchen Sie einen custom deleter überhaupt?Wenn Sie wollen einfach nur etwas code ausgeführt werden, die auf Zerstörung aus sind, dann legen Sie es in einen Destruktor! So können Sie auch immer noch verwenden Sie es mit
make_shared
z.B.Dies gibt Ihnen eine
shared_ptr<int>
erstellt wirdmake_shared
(so bekommt man den Speicher Optimierungen durchgeführt, indemmake_shared
), die ausgeführt wird, einige benutzerdefinierte code auf Zerstörung.Wenn du einen custom deleter Sie nicht verwenden können
make_unique
odermake_shared
Funktionen beim erstellen einer smart-pointer-Objekte . Da müssen wir bieten unseren custom deleter diese Funktionen nicht unterstützen .Nicht verwenden make_unique oder make_shared wenn Sie einen custom deleter oder die Annahme einer raw-Zeiger von anderswo.
Die Idee ist, wenn Sie brauchen eine spezielle Art und Weise löschen Sie Ihr Objekt, das Sie wahrscheinlich brauchen eine spezielle Art und Weise zu schaffen, Sie auch .
Lassen Sie uns sagen, dass wir eine Test-Klasse
Aber wenn man make_shared-Funktion wird ein compiler-Fehler
Grundsätzlich make_shared Funktion ist ein wrapper für
new
unddelete
und wenn Sie möchten, eine custom deleter Sie haben, um Sie eigenennew
unddelete