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, nebo

  • je-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é funkce shared_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é.

spshared_ptr<Other>: Objekt, který vlastní prostředek, který se má spravovat.

wpweak_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é

Jméno 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ý spodkazuje , apnebo 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 *thissp, 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