Třída shared_ptr
Zabalí inteligentní ukazatel počítaný odkazy do dynamicky alokovaného objektu.
Syntaxe
template <class T>
class shared_ptr;
Poznámky
Třída shared_ptr
popisuje objekt, který používá počítání odkazů ke správě prostředků. shared_ptr
Objekt efektivně uchovává ukazatel na prostředek, který vlastní, nebo obsahuje ukazatel null. Prostředek může vlastnit více než jeden shared_ptr
objekt. Když dojde ke zničení posledního shared_ptr
objektu, který vlastní určitý prostředek, uvolní se prostředek.
Když shared_ptr
se prostředek znovu přiřazuje nebo resetuje, přestane vlastnit prostředek.
Argument šablony T
může být neúplný typ s výjimkou toho, jak je uvedeno pro některé členské funkce.
Je-li shared_ptr<T>
objekt vytvořen z ukazatele prostředku typu G*
nebo z shared_ptr<G>
, musí být typ G*
ukazatele konvertibilní na T*
. Pokud není konvertibilní, kód se nezkompiluje. Příklad:
#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>
shared_ptr
Objekt vlastní prostředek:
pokud byl vytvořen s ukazatelem na tento prostředek,
pokud byl vytvořen z objektu
shared_ptr
, který tento prostředek vlastní,pokud byl vytvořen z objektu
weak_ptr
, který odkazuje na tento prostředek, neboje-li k němu přiřazeno vlastnictví tohoto prostředku, a to buď s
shared_ptr::operator=
voláním členské funkce, nebo voláním členské funkceshared_ptr::reset
.
Objekty shared_ptr
, které vlastní prostředek, sdílejí řídicí blok. Řídicí blok obsahuje:
počet
shared_ptr
objektů, které vlastní prostředek,počet
weak_ptr
objektů, které odkazují na prostředek,odstranitel pro tento prostředek, pokud ho má,
vlastní alokátor řídicího bloku, pokud ho má.
shared_ptr
Objekt inicializovaný pomocí ukazatele null má řídicí blok a není prázdný. Jakmile shared_ptr
objekt uvolní prostředek, už tento prostředek nevlastní. Jakmile weak_ptr
objekt uvolní prostředek, přestane odkazovat na tento prostředek.
Když se počet shared_ptr
objektů, které vlastní prostředek, změní na nulu, uvolní se prostředek tím, že ho odstraníte nebo předáte jeho adresu odstraňovači v závislosti na tom, jak bylo původně vytvořeno vlastnictví prostředku. Pokud je shared_ptr
počet objektů, které vlastní prostředek, nula a počet weak_ptr
objektů, které odkazují na tento prostředek, je nulový, uvolní se řídicí blok pomocí vlastního alokátoru pro řídicí blok, pokud má jeden.
Prázdný shared_ptr
objekt nevlastní žádné prostředky a nemá žádný řídicí blok.
Deleter je objekt funkce, který má členovou funkci operator()
. Jeho typ musí být konstruktovatelný a jeho konstruktor kopírování a destruktor nesmí vyvolat výjimky. Přijímá jeden parametr, objekt, který se má odstranit.
Některé funkce přebírají seznam argumentů, který definuje vlastnosti výsledného shared_ptr<T>
objektu nebo weak_ptr<T>
objektu. Takový seznam argumentů můžete zadat několika způsoby:
žádné argumenty: Výsledný objekt je prázdný shared_ptr
nebo prázdný weak_ptr
objekt.
ptr
: Ukazatel typu Other*
na prostředek, který se má spravovat. T
musí být úplný typ. Pokud funkce selže (protože řídicí blok nelze přidělit), vyhodnotí výraz delete ptr
.
ptr, deleter
: Ukazatel typu Other*
na prostředek, který se má spravovat, a odstraňovač pro tento prostředek. Pokud funkce selže (protože řídicí blok nelze přidělit), zavolá deleter(ptr)
, což musí být dobře definované.
ptr, deleter, alloc
: Ukazatel typu Other*
na prostředek, který se má spravovat, odstraňovač pro daný prostředek a alokátor pro správu libovolného úložiště, které musí být přiděleno a uvolněno. Pokud funkce selže (protože řídicí blok nelze přidělit), zavolá deleter(ptr)
, což musí být dobře definované.
sp
shared_ptr<Other>
: Objekt, který vlastní prostředek, který se má spravovat.
wp
weak_ptr<Other>
: Objekt, který odkazuje na prostředek, který se má spravovat.
ap
: Objekt auto_ptr<Other>
, který obsahuje ukazatel na prostředek, který se má spravovat. Pokud je funkce úspěšná, zavolá ap.release()
; jinak zůstane ap
beze změny.
Ve všech případech musí být typ Other*
ukazatele konvertibilní na T*
.
Bezpečný přístup z více vláken
Více vláken může najednou číst a zapisovat různé shared_ptr
objekty, i když jsou objekty kopiemi, které sdílejí vlastnictví.
Členové
Název | Popis |
---|---|
Konstruktory | |
shared_ptr |
Vytvoří .shared_ptr |
~shared_ptr |
Zničí .shared_ptr |
Definice typedef | |
element_type |
Typ prvku |
weak_type |
Typ slabého ukazatele na prvek. |
Členské funkce | |
get |
Získá adresu vlastněného prostředku. |
owner_before |
Vrátí hodnotu true, pokud je tato shared_ptr hodnota seřazena před zadaným ukazatelem (nebo menší než). |
reset |
Nahraďte vlastněný prostředek. |
swap |
Prohodí dva shared_ptr objekty. |
unique |
Testuje, jestli je vlastněný prostředek jedinečný. |
use_count |
Spočítá počet vlastníků prostředků. |
Operátory | |
operator bool |
Testuje, jestli existuje vlastněný prostředek. |
operator* |
Získá určenou hodnotu. |
operator= |
Nahradí vlastněný prostředek. |
operator-> |
Získá ukazatel na určenou hodnotu. |
element_type
Typ prvku
typedef T element_type; // before C++17
using element_type = remove_extent_t<T>; // C++17
Poznámky
Typ element_type
je synonymem pro parametr T
šablony .
Příklad
// 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
Získá adresu vlastněného prostředku.
element_type* get() const noexcept;
Poznámky
Členová funkce vrátí adresu vlastněného prostředku. Pokud objekt nevlastní prostředek, vrátí hodnotu 0.
Příklad
// 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
Testuje, jestli existuje vlastněný prostředek.
explicit operator bool() const noexcept;
Poznámky
Operátor vrátí hodnotu true
, pokud get() != nullptr
, jinak false
.
Příklad
// 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*
Získá určenou hodnotu.
T& operator*() const noexcept;
Poznámky
Operátor indirection vrátí *get()
. Uložený ukazatel proto nesmí být null.
Příklad
// 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=
Nahradí vlastněný prostředek.
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);
Parametry
sp
Sdílený ukazatel pro zkopírování nebo přesunutí.
ap
Automatický ukazatel, který se má přesunout. Přetížení auto_ptr
je zastaralé v jazyce C++11 a odebráno v jazyce C++17.
up
Jedinečný ukazatel na objekt pro přijetí vlastnictví. up
vlastní žádný objekt po volání.
Other
Typ objektu, na který sp
odkazuje , ap
nebo up
.
Deleter
Typ odstraňovače vlastněného objektu uložený pro pozdější odstranění objektu.
Poznámky
Operátory všechny dekrementují počet odkazů pro prostředek, který aktuálně vlastní *this
, a přiřazují vlastnictví prostředku pojmenovaného pořadím operandu *this
. Pokud počet odkazů klesne na nulu, prostředek se uvolní. Pokud se operátor nezdaří, zůstane *this
beze změny.
Příklad
// 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->
Získá ukazatel na určenou hodnotu.
T* operator->() const noexcept;
Poznámky
Operátor výběru vrátí get()
, aby se výraz sp->member
chová stejně jako (sp.get())->member
kde sp
je objekt třídy shared_ptr<T>
. Proto uložený ukazatel nesmí být null a T
musí být třída, struktura nebo sjednocovacího typu s členem member
.
Příklad
// 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
Vrátí hodnotu true, pokud je tato shared_ptr
hodnota seřazena před zadaným ukazatelem (nebo menší než).
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;
Parametry
ptr
Lvalue odkaz na buď a shared_ptr
nebo .weak_ptr
Poznámky
Členová funkce šablony vrátí hodnotu true, pokud *this
je seřazena před ptr
.
reset
Nahraďte vlastněný prostředek.
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);
Parametry
Other
Typ řízený ukazatelem argumentu.
Deleter
Typ odstraňovače.
ptr
Ukazatel, který chcete zkopírovat.
deleter
Odstraňovač, který chcete zkopírovat.
Allocator
Typ alokátoru.
alloc
Alokátor, který se má zkopírovat.
Poznámky
Operátory všechny dekrementují počet odkazů pro prostředek, který aktuálně vlastní *this
, a přiřazují vlastnictví prostředku pojmenovaného pořadím operandu *this
. Pokud počet odkazů klesne na nulu, prostředek se uvolní. Pokud se operátor nezdaří, zůstane *this
beze změny.
Příklad
// 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
Vytvoří .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;
Parametry
Other
Typ řízený ukazatelem argumentu.
ptr
Ukazatel, který chcete zkopírovat.
Deleter
Typ odstraňovače.
Allocator
Typ alokátoru.
deleter
Odstraňovač.
alloc
Alokátor.
sp
Inteligentní ukazatel, který chcete zkopírovat.
wp
Slabý ukazatel.
ap
Automatický ukazatel, který chcete zkopírovat.
Poznámky
Konstruktory každý konstruktor vytvoří objekt, který vlastní prostředek pojmenovaný pořadím operandu. Konstruktor shared_ptr(const weak_ptr<Other>& wp)
vyvolá objekt výjimky typu bad_weak_ptr
if wp.expired()
.
Příklad
// 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
Zničí .shared_ptr
~shared_ptr();
Poznámky
Destruktor dekrementuje počet odkazů pro prostředek, který aktuálně vlastní *this
. Pokud počet odkazů klesne na nulu, prostředek se uvolní.
Příklad
// 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
Prohodí dva shared_ptr
objekty.
void swap(shared_ptr& sp) noexcept;
Parametry
sp
Sdílený ukazatel, se kterým se má prohodit.
Poznámky
Členová funkce ponechá zdroj původně vlastněný následně vlastněným *this
sp
, a zdroj původně vlastněný sp
následně vlastněným *this
. Funkce nezmění počty odkazů pro oba prostředky a nevyvolá žádné výjimky.
Příklad
// 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
Testuje, jestli je vlastněný prostředek jedinečný. Tato funkce byla v jazyce C++17 zastaralá a odebrána v jazyce C++20.
bool unique() const noexcept;
Poznámky
Členová funkce vrátí, true
pokud žádný jiný shared_ptr
objekt nevlastní prostředek, který vlastní *this
, jinak false
.
Příklad
// 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
Spočítá počet vlastníků prostředků.
long use_count() const noexcept;
Poznámky
Členová funkce vrátí počet shared_ptr
objektů, které vlastní prostředek, který vlastní *this
.
Příklad
// 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
Typ slabého ukazatele na prvek.
using weak_type = weak_ptr<T>; // C++17
Poznámky
Definice weak_type
byla přidána v jazyce C++17.
Viz také
Referenční informace k souborům hlaviček
<memory>
unique_ptr
Třída weak_ptr