Namensräume
Varianten
Aktionen

std::shared_ptr<T>::reset

Von cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
Speicherverwaltungsbibliothek
(nur Exposition*)
Algorithmen für uninitialisierten Speicher
(C++17)
(C++17)
(C++17)
Beschränkte uninitialisierte
Speicher-Algorithmen
C-Bibliothek

Allocatoren
Speicherressourcen
Unterstützung für Garbage Collection
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
Uninitialisierter Speicher
Explizites Lebenszeitmanagement
 
 
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ä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 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

#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) [edit]