std::shared_ptr<T>::reset
Von cppreference.com
< cpp | memory | shared ptr
| void reset() noexcept; |
(1) | (seit C++11) |
| template< class Y > void reset( Y* ptr ); |
(2) | (seit C++11) |
| template< class Y, class Deleter > void reset( Y* ptr, Deleter d ); |
(3) | (seit C++11) |
| template< class Y, class Deleter, class Alloc > void reset( Y* ptr, Deleter d, Alloc alloc ); |
(4) | (seit C++11) |
Ersetzt das verwaltete Objekt durch ein Objekt, auf das ptr zeigt. Optional kann ein Deleter d angegeben werden, der später zum Zerstören des neuen Objekts verwendet wird, wenn kein shared_ptr dieses Objekt besitzt. Standardmäßig wird der delete-Ausdruck als Deleter verwendet. Der passende delete-Ausdruck für den angegebenen Typ wird immer ausgewählt, weshalb die Funktion als Template mit einem separaten Parameter Y implementiert ist.
Wenn *this bereits ein Objekt besitzt und dies der letzte shared_ptr ist, der es besitzt, wird das Objekt über den besessenen Deleter zerstört.
Wenn das Objekt, auf das ptr zeigt, bereits besessen wird, führt die Funktion im Allgemeinen zu undefiniertem Verhalten.
1) Gibt den Besitz des verwalteten Objekts frei, falls vorhanden. Nach dem Aufruf verwaltet *this kein Objekt mehr. Äquivalent zu shared_ptr().swap(*this);.
2-4) Ersetzt das verwaltete Objekt durch ein Objekt, auf das ptr zeigt.
Y muss ein vollständiger Typ und implizit in T konvertierbar sein. Zusätzlich2) Verwendet den delete-Ausdruck als Deleter. Ein gültiger delete-Ausdruck muss verfügbar sein, d.h. delete ptr muss wohlgeformt sein, wohldefiniertes Verhalten aufweisen und keine Ausnahmen auslösen. Äquivalent zu shared_ptr<T>(ptr).swap(*this);.
3) Verwendet den angegebenen Deleter d als Deleter.
Deleter muss für den Typ T aufrufbar sein, d.h. d(ptr) muss wohlgeformt sein, wohldefiniertes Verhalten aufweisen und keine Ausnahmen auslösen. Deleter muss CopyConstructible sein, und sein Kopierkonstruktor und Destruktor dürfen keine Ausnahmen auslösen. Äquivalent zu shared_ptr<T>(ptr, d).swap(*this);.4) Ähnlich wie (3), verwendet aber zusätzlich eine Kopie von alloc für die Allokation von Daten für die interne Verwendung.
Alloc muss ein Allocator sein. Der Kopierkonstruktor und Destruktor dürfen keine Ausnahmen auslösen. Äquivalent zu shared_ptr<T>(ptr, d, alloc).swap(*this);.Inhalt |
[edit] Parameter
| ptr | - | Zeiger auf ein Objekt, dessen Besitz übernommen werden soll |
| d | - | Deleter, der für die Löschung des Objekts gespeichert werden soll |
| alloc | - | Allocator, der für interne Allokationen verwendet werden soll |
[edit] Rückgabewert
(keine)
[edit] Ausnahmen
2) std::bad_alloc, wenn erforderlicher zusätzlicher Speicher nicht beschafft werden konnte. Kann eine implementierungsdefinierte Ausnahme für andere Fehler auslösen. delete ptr wird aufgerufen, wenn ein Fehler auftritt.
3,4) std::bad_alloc, wenn erforderlicher zusätzlicher Speicher nicht beschafft werden konnte. Kann eine implementierungsdefinierte Ausnahme für andere Fehler auslösen. d(ptr) wird aufgerufen, wenn ein Fehler auftritt.
[edit] Beispiel
Führen Sie diesen Code aus
#include <iostream> #include <memory> struct Foo { Foo(int n = 0) noexcept : bar(n) { std::cout << "Foo::Foo(), bar = " << bar << " @ " << this << '\n'; } ~Foo() { std::cout << "Foo::~Foo(), bar = " << bar << " @ " << this << '\n'; } int getBar() const noexcept { return bar; } private: int bar; }; int main() { std::cout << "1) unique ownership\n"; { std::shared_ptr<Foo> sptr = std::make_shared<Foo>(100); std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = " << sptr.use_count() << '\n'; // Reset the shared_ptr without handing it a fresh instance of Foo. // The old instance will be destroyed after this call. std::cout << "call sptr.reset()...\n"; sptr.reset(); // calls Foo's destructor here std::cout << "After reset(): use_count() = " << sptr.use_count() << ", sptr = " << sptr << '\n'; } // No call to Foo's destructor, it was done earlier in reset(). std::cout << "\n2) unique ownership\n"; { std::shared_ptr<Foo> sptr = std::make_shared<Foo>(200); std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = " << sptr.use_count() << '\n'; // Reset the shared_ptr, hand it a fresh instance of Foo. // The old instance will be destroyed after this call. std::cout << "call sptr.reset()...\n"; sptr.reset(new Foo{222}); std::cout << "After reset(): use_count() = " << sptr.use_count() << ", sptr = " << sptr << "\nLeaving the scope...\n"; } // Calls Foo's destructor. std::cout << "\n3) multiple ownership\n"; { std::shared_ptr<Foo> sptr1 = std::make_shared<Foo>(300); std::shared_ptr<Foo> sptr2 = sptr1; std::shared_ptr<Foo> sptr3 = sptr2; std::cout << "Foo::bar = " << sptr1->getBar() << ", use_count() = " << sptr1.use_count() << '\n'; // Reset the shared_ptr sptr1, hand it a fresh instance of Foo. // The old instance will stay shared between sptr2 and sptr3. std::cout << "call sptr1.reset()...\n"; sptr1.reset(new Foo{333}); std::cout << "After reset():\n" << "sptr1.use_count() = " << sptr1.use_count() << ", sptr1 @ " << sptr1 << '\n' << "sptr2.use_count() = " << sptr2.use_count() << ", sptr2 @ " << sptr2 << '\n' << "sptr3.use_count() = " << sptr3.use_count() << ", sptr3 @ " << sptr3 << '\n' << "Leaving the scope...\n"; } // Calls two destructors of: 1) Foo owned by sptr1, // 2) Foo shared between sptr2/sptr3. }
Mögliche Ausgabe
1) unique ownership Foo::Foo(), bar = 100 @ 0x23c5040 Foo::bar = 100, use_count() = 1 call sptr.reset()... Foo::~Foo(), bar = 100 @ 0x23c5040 After reset(): use_count() = 0, sptr = 0 2) unique ownership Foo::Foo(), bar = 200 @ 0x23c5040 Foo::bar = 200, use_count() = 1 call sptr.reset()... Foo::Foo(), bar = 222 @ 0x23c5050 Foo::~Foo(), bar = 200 @ 0x23c5040 After reset(): use_count() = 1, sptr = 0x23c5050 Leaving the scope... Foo::~Foo(), bar = 222 @ 0x23c5050 3) multiple ownership Foo::Foo(), bar = 300 @ 0x23c5080 Foo::bar = 300, use_count() = 3 call sptr1.reset()... Foo::Foo(), bar = 333 @ 0x23c5050 After reset(): sptr1.use_count() = 1, sptr1 @ 0x23c5050 sptr2.use_count() = 2, sptr2 @ 0x23c5080 sptr3.use_count() = 2, sptr3 @ 0x23c5080 Leaving the scope... Foo::~Foo(), bar = 300 @ 0x23c5080 Foo::~Foo(), bar = 333 @ 0x23c5050
[edit] Siehe auch
erstellt einen neuen shared_ptr(public member function) |