Namespaces
Variants

std::shared_ptr<T>:: reset

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
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.

1) Gibt das Eigentum des verwalteten Objekts frei, falls vorhanden. Nach dem Aufruf * this verwaltet kein Objekt mehr. Entspricht shared_ptr ( ) . swap ( * this ) ; .
2-4) Ersetzt das verwaltete Objekt mit einem Objekt, auf das ptr zeigt. Y muss ein vollständiger Typ sein und implizit in T konvertierbar sein. Zusätzlich:
2) 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 werfen. Ä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 werfen. Deleter muss CopyConstructible sein, und sein Kopierkonstruktor sowie Destruktor dürfen keine Ausnahmen werfen. Entspricht shared_ptr < T > ( ptr, d ) . swap ( * this ) ; .
4) Gleich wie (3) , verwendet jedoch zusätzlich eine Kopie von alloc für die Allokation von Daten für interne Verwendung. 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

2) std::bad_alloc falls die benötigte zusätzliche Speichermenge nicht beschafft werden konnte. Kann implementationsdefinierte Ausnahmen für andere Fehler werfen. delete ptr wird aufgerufen, falls eine Ausnahme auftritt.
3,4) std::bad_alloc falls die erforderliche zusätzliche Speichermenge nicht beschafft werden konnte. Kann implementationsdefinierte Ausnahmen für andere Fehler werfen. d ( ptr ) wird aufgerufen, falls eine Ausnahme auftritt.

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)