std::shared_ptr<T>:: reset
|
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
bereitgestellt werden, der später verwendet wird, um das neue Objekt zu zerstören, wenn keine
shared_ptr
-Objekte mehr im Besitz sind. Standardmäßig wird der
delete
-Ausdruck als Deleter verwendet. Der entsprechende
delete
-Ausdruck für den bereitgestellten Typ wird immer ausgewählt. Dies ist der Grund, warum die Funktion als Template mit einem separaten Parameter
Y
implementiert ist.
Wenn
*
this
bereits ein Objekt besitzt und es der letzte
shared_ptr
ist, der es besitzt, wird das Objekt durch den zugehörigen Deleter zerstört.
Wenn das Objekt, auf das ptr zeigt, bereits im Besitz ist, führt die Funktion im Allgemeinen zu undefiniertem Verhalten.
Y
muss ein vollständiger Typ sein und implizit in
T
konvertierbar sein. Zusätzlich:
Deleter
muss für den Typ
T
aufrufbar sein, d.h.
d
(
ptr
)
muss wohlgeformt sein, wohldefiniertes Verhalten aufweisen und keine Ausnahmen werfen.
Deleter
muss
CopyConstructible
sein, und sein Kopierkonstruktor sowie Destruktor dürfen keine Ausnahmen werfen. Entspricht
shared_ptr
<
T
>
(
ptr, d
)
.
swap
(
*
this
)
;
.
Alloc
muss ein
Allocator
sein. Der Kopierkonstruktor und Destruktor dürfen keine Exceptions werfen. Entspricht
shared_ptr
<
T
>
(
ptr, d, alloc
)
.
swap
(
*
this
)
;
.
Inhaltsverzeichnis |
Parameter
| ptr | - | Zeiger auf ein Objekt, dessen Eigentum übernommen werden soll |
| d | - | Deleter, der für die Löschung des Objekts gespeichert wird |
| alloc | - | Allokator, der für interne Allokationen verwendet wird |
Rückgabewert
(keine)
Exceptions
Beispiel
#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) eindeutige Eigentümerschaft\n"; { std::shared_ptr<Foo> sptr = std::make_shared<Foo>(100); std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = " << sptr.use_count() << '\n'; // Setzt den shared_ptr zurück, ohne ihm eine neue Instanz von Foo zu übergeben. // Die alte Instanz wird nach diesem Aufruf zerstört. std::cout << "call sptr.reset()...\n"; sptr.reset(); // ruft hier den Destruktor von Foo auf std::cout << "Nach reset(): use_count() = " << sptr.use_count() << ", sptr = " << sptr << '\n'; } // Kein Aufruf von Foos Destruktor, er wurde bereits früher in reset() durchgeführt. 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'; // Setzt den shared_ptr zurück, übergibt ihm eine neue Instanz von Foo. // Die alte Instanz wird nach diesem Aufruf zerstört. std::cout << "call sptr.reset()...\n"; sptr.reset(new Foo{222}); std::cout << "Nach reset(): use_count() = " << sptr.use_count() << ", sptr = " << sptr << "\nVerlasse den Gültigkeitsbereich...\n"; } // Ruft den Destruktor von Foo auf. 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'; // Setze den shared_ptr sptr1 zurück, übergebe ihm eine neue Instanz von Foo. // Die alte Instanz wird zwischen sptr2 und sptr3 gemeinsam genutzt. std::cout << "call sptr1.reset()...\n"; sptr1.reset(new Foo{333}); std::cout << "Nach 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' << "Verlassen des Gültigkeitsbereichs...\n"; } // Ruft zwei Destruktoren auf: 1) Foo im Besitz von sptr1, // 2) Foo gemeinsam genutzt zwischen sptr2/sptr3. }
Mögliche Ausgabe:
1) Einzelbesitz Foo::Foo(), bar = 100 @ 0x23c5040 Foo::bar = 100, use_count() = 1 Aufruf sptr.reset()... Foo::~Foo(), bar = 100 @ 0x23c5040 Nach reset(): use_count() = 0, sptr = 0 2) Einzelbesitz Foo::Foo(), bar = 200 @ 0x23c5040 Foo::bar = 200, use_count() = 1 Aufruf sptr.reset()... Foo::Foo(), bar = 222 @ 0x23c5050 Foo::~Foo(), bar = 200 @ 0x23c5040 Nach reset(): use_count() = 1, sptr = 0x23c5050 Verlassen des Gültigkeitsbereichs... Foo::~Foo(), bar = 222 @ 0x23c5050 3) Mehrfachbesitz Foo::Foo(), bar = 300 @ 0x23c5080 Foo::bar = 300, use_count() = 3 Aufruf sptr1.reset()... Foo::Foo(), bar = 333 @ 0x23c5050 Nach reset(): sptr1.use_count() = 1, sptr1 @ 0x23c5050 sptr2.use_count() = 2, sptr2 @ 0x23c5080 sptr3.use_count() = 2, sptr3 @ 0x23c5080 Verlassen des Gültigkeitsbereichs... Foo::~Foo(), bar = 300 @ 0x23c5080 Foo::~Foo(), bar = 333 @ 0x23c5050
Siehe auch
erstellt neuen
shared_ptr
(öffentliche Member-Funktion) |