Freigeben über


shared_ptr-Klasse

Umschließt einen intelligenten Zeiger mit Verweiszählung um ein dynamisch zugeordnetes Objekt.

Syntax

template <class T>
class shared_ptr;

Hinweise

Die shared_ptr Klasse beschreibt ein Objekt, das referenziert, um Ressourcen zu verwalten. Ein Objekt vom Typ shared_ptr enthält einen Zeiger auf die Ressource, die es besitzt, oder es enthält einen NULL-Zeiger. Es können mehrere shared_ptr-Objekte eine Ressource besitzen. Wird das letzte shared_ptr-Objekt beschädigt, das eine bestimmte Ressource besitzt, wird die Ressource freigegeben.

Eine shared_ptr Ressource wird nicht mehr besitzen, wenn sie neu zugewiesen oder zurückgesetzt wird.

Das Vorlagenargument T kann ein unvollständiger Typ sein, außer wie für bestimmte Memberfunktionen aufgeführt.

Wenn ein shared_ptr<T>-Objekt von einem Ressourcenzeiger des Typs G* oder von einem shared_ptr<G> erstellt wird, muss der Zeigertyp G* konvertierbar sein in T*. Wenn es nicht konvertierbar ist, wird der Code nicht kompiliert. Zum Beispiel:

#include <memory>
using namespace std;

class F {};
class G : public F {};

shared_ptr<G> sp0(new G);   // okay, template parameter G and argument G*
shared_ptr<G> sp1(sp0);     // okay, template parameter G and argument shared_ptr<G>
shared_ptr<F> sp2(new G);   // okay, G* convertible to F*
shared_ptr<F> sp3(sp0);     // okay, template parameter F and argument shared_ptr<G>
shared_ptr<F> sp4(sp2);     // okay, template parameter F and argument shared_ptr<F>
shared_ptr<int> sp5(new G); // error, G* not convertible to int*
shared_ptr<int> sp6(sp2);   // error, template parameter int and argument shared_ptr<F>

Ein shared_ptr-Objekt besitzt in diesen Fällen eine Ressource:

  • Es wurde mit einem Zeiger auf diese Ressource erstellt.

  • Es wurde von einem shared_ptr-Objekt erstellt, das diese Ressource besitzt.

  • wenn es aus einem weak_ptr Objekt erstellt wurde, das auf diese Ressource verweist, oder

  • wenn ihm der Besitz dieser Ressource zugewiesen wurde, entweder mit shared_ptr::operator= oder durch Aufrufen der Memberfunktion shared_ptr::reset.

Von den shared_ptr-Objekten, die eine Ressource besitzen, wird ein Kontrollblock gemeinsam verwendet. Der Kontrollblock enthält:

  • Die Anzahl von shared_ptr-Objekten, die die Ressource besitzen

  • Die Anzahl von weak_ptr-Objekten, die auf die Ressource verweisen

  • Den Deleter für diese Ressource, falls vorhanden

  • Die benutzerdefinierte Zuweisung für den Kontrollblock, falls vorhanden

Ein shared_ptr Objekt, das mithilfe eines Nullzeigers initialisiert wird, weist einen Steuerelementblock auf und ist nicht leer. Eine von einem shared_ptr-Objekt freigegebene Ressource ist nicht mehr im Besitz dieses Objekts. Nachdem ein weak_ptr-Objekt eine Ressource freigegeben hat, verweist es nicht mehr darauf.

Wenn die Anzahl von shared_ptr-Objekten, die eine Ressource besitzen, Null ergibt, wird die Ressource freigegeben. Dazu wird sie entweder gelöscht, oder ihre Adresse wird an einen Deleter übergeben. Das Verfahren hängt davon ab, wie die Besitzrechte der Ressource ursprünglich erstellt wurden. Wenn die Anzahl von shared_ptr-Objekten, die eine Ressource besitzen, null ist und auch die Anzahl von weak_ptr-Objekten, die auf diese Ressource zeigen, null ist, wird der Kontrollblock freigegeben. Dazu wird die benutzerdefinierte Zuweisung für den Kontrollblock verwendet, falls vorhanden.

Ein leeres shared_ptr Objekt besitzt keine Ressourcen und verfügt über keinen Steuerelementblock.

Ein Deleter ist ein Funktionsobjekt mit einer Memberfunktion operator(). Für den Typ muss eine Kopie erstellt werden können. Vom Kopierkonstruktor und vom Destruktor dürfen keine Ausnahmen ausgelöst werden. Als Parameter akzeptiert wird das zu löschende Objekt.

Von einigen Funktionen wird eine Argumentliste verwendet, mit der Eigenschaften des resultierenden shared_ptr<T>- oder weak_ptr<T>-Objekts definiert werden. Sie können eine solche Argumentliste wie folgt angeben:

keine Argumente: Das resultierende Objekt ist ein leeres shared_ptr Objekt oder ein leeres weak_ptr Objekt.

ptr: Ein Zeiger vom Typ Other* auf die zu verwaltende Ressource. T muss ein vollständiger Typ sein. Wenn die Funktion fehlschlägt (da der Steuerelementblock nicht zugeordnet werden kann), wertet sie den Ausdruck delete ptraus.

ptr, deleter: Ein Zeiger vom Typ Other* auf die zu verwaltende Ressource und ein Löschprogramm für diese Ressource. Wenn die Funktion fehlschlägt (da der Steuerblock nicht zugeordnet werden kann), wird sie aufgerufen deleter(ptr), was gut definiert sein muss.

ptr, deleter, alloc: Ein Zeiger vom Typ Other* auf die zu verwaltende Ressource, ein Löschprogramm für diese Ressource und ein Zuweisungsverteiler zum Verwalten von Speicher, der zugewiesen und freigegeben werden muss. Wenn die Funktion fehlschlägt (da der Steuerblock nicht zugeordnet werden kann), wird sie aufgerufen deleter(ptr), was gut definiert sein muss.

sp: Ein shared_ptr<Other> Objekt, das die zu verwaltende Ressource besitzt.

wp: Ein weak_ptr<Other> Objekt, das auf die zu verwaltende Ressource verweist.

ap: Ein auto_ptr<Other> Objekt, das einen Zeiger auf die zu verwaltende Ressource enthält. Wenn die Funktion erfolgreich ist, wird sie aufgerufen ap.release(); andernfalls bleibt ap sie unverändert.

In allen Fällen muss der Zeigertyp Other* konvertiert werden können in T*.

Threadsicherheit

Mehrere Threads können verschiedene shared_ptr-Objekte gleichzeitig lesen und schreiben, auch wenn die Objekte Kopien sind, die sich den Besitz teilen.

Mitglieder

Name Beschreibung
Konstruktoren
shared_ptr Erstellt ein Objekt vom Typ shared_ptr.
~shared_ptr Beschädigt ein Objekt vom Typ shared_ptr.
TypeDefs
element_type Der Typ eines Elements.
weak_type Der Typ eines schwachen Zeigers auf ein Element.
Memberfunktionen
get Ruft die Adresse der Ressource ab, die Eigentum ist.
owner_before Gibt True zurück, wenn dieses shared_ptr vor dem bereitgestellten Zeiger sortiert wird (Operator "Before" oder "Less than").
reset Ersetzt die Ressource, die Eigentum ist.
swap Tauscht zwei shared_ptr-Objekte.
unique Prüft, ob die Ressource eindeutig ist, die Eigentum ist.
use_count Zählt Ressourcenbesitzer.
Operatoren
operator bool Prüft, ob eine Ressource vorhanden ist, die Eigentum ist.
operator* Ruft den angegebenen Wert ab.
operator= Ersetzt die Ressource, die Eigentum ist.
operator-> Ruft einen Zeiger auf den angegebenen Wert ab.

element_type

Der Typ eines Elements.

typedef T element_type;                  // before C++17
using element_type = remove_extent_t<T>; // C++17

Hinweise

Der element_type Typ ist ein Synonym für den Vorlagenparameter T.

Beispiel

// std__memory__shared_ptr_element_type.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp0(new int(5));
    std::shared_ptr<int>::element_type val = *sp0;

    std::cout << "*sp0 == " << val << std::endl;

    return (0);
}
*sp0 == 5

get

Ruft die Adresse der Ressource ab, die Eigentum ist.

element_type* get() const noexcept;

Hinweise

Die Memberfunktion gibt die Adresse der im Besitz befindlichen Ressource zurück. Wenn das Objekt keine Ressource besitzt, wird 0 zurückgegeben.

Beispiel

// std__memory__shared_ptr_get.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp0;
    std::shared_ptr<int> sp1(new int(5));

    std::cout << "sp0.get() == 0 == " << std::boolalpha
        << (sp0.get() == 0) << std::endl;
    std::cout << "*sp1.get() == " << *sp1.get() << std::endl;

    return (0);
}
sp0.get() == 0 == true
*sp1.get() == 5

operator bool

Prüft, ob eine Ressource vorhanden ist, die Eigentum ist.

explicit operator bool() const noexcept;

Hinweise

Der Operator gibt einen Wert zurück, wenn true get() != nullptr, andernfalls false.

Beispiel

// std__memory__shared_ptr_operator_bool.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp0;
    std::shared_ptr<int> sp1(new int(5));

    std::cout << "(bool)sp0 == " << std::boolalpha
        << (bool)sp0 << std::endl;
    std::cout << "(bool)sp1 == " << std::boolalpha
        << (bool)sp1 << std::endl;

    return (0);
}
(bool)sp0 == false
(bool)sp1 == true

operator*

Ruft den angegebenen Wert ab.

T& operator*() const noexcept;

Hinweise

Der Dereferenzierungsoperator gibt *get() zurück. Daher darf der gespeicherte Zeiger nicht NULL sein.

Beispiel

// std__memory__shared_ptr_operator_st.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp0(new int(5));

    std::cout << "*sp0 == " << *sp0 << std::endl;

    return (0);
}
*sp0 == 5

operator=

Ersetzt die Ressource, die Eigentum ist.

shared_ptr& operator=(const shared_ptr& sp) noexcept;

shared_ptr& operator=(shared_ptr&& sp) noexcept;

template <class Other>
shared_ptr& operator=(const shared_ptr<Other>& sp) noexcept;

template <class Other>
shared_ptr& operator=(shared_ptr<Other>&& sp) noexcept;

template <class Other>
shared_ptr& operator=(auto_ptr<Other>&& ap);    // deprecated in C++11, removed in C++17

template <class Other, class Deleter>
shared_ptr& operator=(unique_ptr<Other, Deleter>&& up);

Parameter

sp
Der freigegebene Zeiger, aus dem kopiert oder verschoben werden soll.

ap
Der automatische Zeiger, der verschoben werden soll. Die auto_ptr Überladung ist in C++11 veraltet und in C++17 entfernt.

up
Der eindeutige Zeiger auf das Objekt, an dem der Besitz angenommen werden soll. up besitzt kein Objekt nach dem Aufruf.

Other
Der Typ des Objekts, auf das durch sp, , apoder up.

Deleter
Der Typ des Löschvorgangs des besitzeigenen Objekts, der für das spätere Löschen des Objekts gespeichert ist.

Hinweise

Alle Operatoren verringern die Verweisanzahl für die Ressource frei, die derzeit im Besitz von *this steht, und weisen den Besitz der Ressource, die von der Operatorsequenz benannt wird, *this zu. Wenn die Verweisanzahl auf 0 (null) fällt, wird die Ressource freigegeben. Wenn ein Operator fehlschlägt, bleibt *this er unverändert.

Beispiel

// std__memory__shared_ptr_operator_as.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp0;
    std::shared_ptr<int> sp1(new int(5));
    std::unique_ptr<int> up(new int(10));

    sp0 = sp1;
    std::cout << "*sp0 == " << *sp0 << std::endl;

    sp0 = up;
    std::cout << "*sp0 == " << *sp0 << std::endl;

    return (0);
}
*sp0 == 5
*sp0 == 10

operator->

Ruft einen Zeiger auf den angegebenen Wert ab.

T* operator->() const noexcept;

Hinweise

Der Auswahloperator gibt get() zurück, sodass der Ausdruck sp->member sich wie (sp.get())->member verhält, wobei sp ein Objekt von Klasse shared_ptr<T> ist. Daher darf der gespeicherte Zeiger nicht NULL sein, und T muss eine Klasse, eine Struktur oder ein Union-Typ mit einem member-member sein.

Beispiel

// std__memory__shared_ptr_operator_ar.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

typedef std::pair<int, int> Mypair;
int main()
{
    std::shared_ptr<Mypair> sp0(new Mypair(1, 2));

    std::cout << "sp0->first == " << sp0->first << std::endl;
    std::cout << "sp0->second == " << sp0->second << std::endl;

    return (0);
}
sp0->first == 1
sp0->second == 2

owner_before

Gibt True zurück, wenn dieses shared_ptr vor dem bereitgestellten Zeiger sortiert wird (Operator "Before" oder "Less than").

template <class Other>
bool owner_before(const shared_ptr<Other>& ptr) const noexcept;

template <class Other>
bool owner_before(const weak_ptr<Other>& ptr) const noexcept;

Parameter

ptr
Ein lvalue-Verweis auf ein shared_ptr oder ein weak_ptr.

Hinweise

Die Elementfunktion der Vorlage gibt "true" zurück, wenn *this sie vor ptrgeordnet ist.

reset

Ersetzt die Ressource, die Eigentum ist.

void reset() noexcept;

template <class Other>
void reset(Other *ptr);

template <class Other, class Deleter>
void reset(
    Other *ptr,
    Deleter deleter);

template <class Other, class Deleter, class Allocator>
void reset(
    Other *ptr,
    Deleter deleter,
    Allocator alloc);

Parameter

Other
Der vom Argumentzeiger gesteuerte Typ.

Deleter
Der Deleter-Typ.

ptr
Der zu kopierende Zeiger.

deleter
Der zu kopierende Deleter.

Allocator
Der Zuweisungstyp.

alloc
Der zu kopierende Zuweiser.

Hinweise

Alle Operatoren verringern die Verweisanzahl für die Ressource frei, die derzeit im Besitz von *this steht, und weisen den Besitz der Ressource, die von der Operatorsequenz benannt wird, *this zu. Wenn die Verweisanzahl auf 0 (null) fällt, wird die Ressource freigegeben. Wenn ein Operator fehlschlägt, bleibt *this er unverändert.

Beispiel

// std__memory__shared_ptr_reset.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

struct deleter
{
    void operator()(int *p)
    {
        delete p;
    }
};

int main()
{
    std::shared_ptr<int> sp(new int(5));

    std::cout << "*sp == " << std::boolalpha
        << *sp << std::endl;

    sp.reset();
    std::cout << "(bool)sp == " << std::boolalpha
        << (bool)sp << std::endl;

    sp.reset(new int(10));
    std::cout << "*sp == " << std::boolalpha
        << *sp << std::endl;

    sp.reset(new int(15), deleter());
    std::cout << "*sp == " << std::boolalpha
        << *sp << std::endl;

    return (0);
}
*sp == 5
(bool)sp == false
*sp == 10
*sp == 15

shared_ptr

Erstellt ein Objekt vom Typ shared_ptr.

constexpr shared_ptr() noexcept;

constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() {}

shared_ptr(const shared_ptr& sp) noexcept;

shared_ptr(shared_ptr&& sp) noexcept;

template <class Other>
explicit shared_ptr(Other* ptr);

template <class Other, class Deleter>
shared_ptr(
    Other* ptr,
    Deleter deleter);

template <class Deleter>
shared_ptr(
    nullptr_t ptr,
    Deleter deleter);

template <class Other, class Deleter, class Allocator>
shared_ptr(
    Other* ptr,
    Deleter deleter,
    Allocator alloc);

template <class Deleter, class Allocator>
shared_ptr(
    nullptr_t ptr,
    Deleter deleter,
    Allocator alloc);

template <class Other>
shared_ptr(
    const shared_ptr<Other>& sp) noexcept;

template <class Other>
explicit shared_ptr(
    const weak_ptr<Other>& wp);

template <class &>
shared_ptr(
    std::auto_ptr<Other>& ap);

template <class &>
shared_ptr(
    std::auto_ptr<Other>&& ap);

template <class Other, class Deleter>
shared_ptr(
    unique_ptr<Other, Deleter>&& up);

template <class Other>
shared_ptr(
    const shared_ptr<Other>& sp,
    element_type* ptr) noexcept;

template <class Other>
shared_ptr(
    shared_ptr<Other>&& sp,
    element_type* ptr) noexcept;

template <class Other, class Deleter>
shared_ptr(
    const unique_ptr<Other, Deleter>& up) = delete;

Parameter

Other
Der vom Argumentzeiger gesteuerte Typ.

ptr
Der zu kopierende Zeiger.

Deleter
Der Deleter-Typ.

Allocator
Der Zuweisungstyp.

deleter
Der Deleter.

alloc
Die Zuweisung.

sp
Der zu kopierende intelligente Zeiger.

wp
Der schwache Zeiger.

ap
Der zu kopierende automatische Zeiger

Hinweise

Die Konstruktoren erstellen jeweils ein Objekt, dem die Ressource gehört, die von der Operatorensequenz benannt wird. Der Konstruktor shared_ptr(const weak_ptr<Other>& wp) löst ein Ausnahmeobjekt des Typs bad_weak_ptr aus, wenn wp.expired().

Beispiel

// std__memory__shared_ptr_construct.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

struct deleter
{
    void operator()(int *p)
    {
        delete p;
    }
};

int main()
{
    std::shared_ptr<int> sp0;
    std::cout << "(bool)sp0 == " << std::boolalpha
        << (bool)sp0 << std::endl;

    std::shared_ptr<int> sp1(new int(5));
    std::cout << "*sp1 == " << *sp1 << std::endl;

    std::shared_ptr<int> sp2(new int(10), deleter());
    std::cout << "*sp2 == " << *sp2 << std::endl;

    std::shared_ptr<int> sp3(sp2);
    std::cout << "*sp3 == " << *sp3 << std::endl;

    std::weak_ptr<int> wp(sp3);
    std::shared_ptr<int> sp4(wp);
    std::cout << "*sp4 == " << *sp4 << std::endl;

    std::auto_ptr<int> ap(new int(15));
    std::shared_ptr<int> sp5(ap);
    std::cout << "*sp5 == " << *sp5 << std::endl;

    return (0);
}
(bool)sp0 == false
*sp1 == 5
*sp2 == 10
*sp3 == 10
*sp4 == 10
*sp5 == 15

~shared_ptr

Beschädigt ein Objekt vom Typ shared_ptr.

~shared_ptr();

Hinweise

Der Destruktor verringert die Verweisanzahl für die Ressource, die derzeit im Besitz von *this ist. Wenn die Verweisanzahl auf 0 (null) fällt, wird die Ressource freigegeben.

Beispiel

// std__memory__shared_ptr_destroy.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp1(new int(5));
    std::cout << "*sp1 == " << *sp1 << std::endl;
    std::cout << "use count == " << sp1.use_count() << std::endl;

    {
        std::shared_ptr<int> sp2(sp1);
        std::cout << "*sp2 == " << *sp2 << std::endl;
        std::cout << "use count == " << sp1.use_count() << std::endl;
    }

    // check use count after sp2 is destroyed
    std::cout << "use count == " << sp1.use_count() << std::endl;

    return (0);
}
*sp1 == 5
use count == 1
*sp2 == 5
use count == 2
use count == 1

swap

Tauscht zwei shared_ptr-Objekte.

void swap(shared_ptr& sp) noexcept;

Parameter

sp
Der gemeinsame Zeiger, mit dem getauscht werden soll.

Hinweise

Die Memberfunktion belässt die Ressource, die ursprünglich im Besitz von *this und anschließend von sp war, und die Ressource, die ursprünglich im Besitz von sp und anschließend von *this war. Die Funktion ändert die Verweisanzahl für die beiden Ressourcen nicht und löst keine Ausnahmen aus.

Beispiel

// std__memory__shared_ptr_swap.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp1(new int(5));
    std::shared_ptr<int> sp2(new int(10));
    std::cout << "*sp1 == " << *sp1 << std::endl;

    sp1.swap(sp2);
    std::cout << "*sp1 == " << *sp1 << std::endl;

    swap(sp1, sp2);
    std::cout << "*sp1 == " << *sp1 << std::endl;
    std::cout << std::endl;

    std::weak_ptr<int> wp1(sp1);
    std::weak_ptr<int> wp2(sp2);
    std::cout << "*wp1 == " << *wp1.lock() << std::endl;

    wp1.swap(wp2);
    std::cout << "*wp1 == " << *wp1.lock() << std::endl;

    swap(wp1, wp2);
    std::cout << "*wp1 == " << *wp1.lock() << std::endl;

    return (0);
}
*sp1 == 5
*sp1 == 10
*sp1 == 5
*wp1 == 5
*wp1 == 10
*wp1 == 5

unique

Prüft, ob die Ressource eindeutig ist, die Eigentum ist. Diese Funktion wurde in C++17 veraltet und in C++20 entfernt.

bool unique() const noexcept;

Hinweise

Die Memberfunktion gibt true zurück, wenn kein anderes shared_ptr-Objekt die Ressource besitzt, die im Besitz von *this, andernfalls false.

Beispiel

// std__memory__shared_ptr_unique.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp1(new int(5));
    std::cout << "sp1.unique() == " << std::boolalpha
        << sp1.unique() << std::endl;

    std::shared_ptr<int> sp2(sp1);
    std::cout << "sp1.unique() == " << std::boolalpha
        << sp1.unique() << std::endl;

    return (0);
}
sp1.unique() == true
sp1.unique() == false

use_count

Zählt Ressourcenbesitzer.

long use_count() const noexcept;

Hinweise

Die Memberfunktion gibt die Anzahl von shared_ptr-Objekten zurück, die die Ressource besitzen, die im Besitz von *this ist.

Beispiel

// std__memory__shared_ptr_use_count.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>

int main()
{
    std::shared_ptr<int> sp1(new int(5));
    std::cout << "sp1.use_count() == "
        << sp1.use_count() << std::endl;

    std::shared_ptr<int> sp2(sp1);
    std::cout << "sp1.use_count() == "
        << sp1.use_count() << std::endl;

    return (0);
}
sp1.use_count() == 1
sp1.use_count() == 2

weak_type

Der Typ eines schwachen Zeigers auf ein Element.

using weak_type = weak_ptr<T>; // C++17

Hinweise

Die weak_type Definition wurde in C++17 hinzugefügt.

Siehe auch

Headerdateienreferenz
<memory>
unique_ptr
weak_ptr-Klasse