Klasa shared_ptr

Otacza inteligentny wskaźnik zliczonych odwołań wokół obiektu przydzielanego dynamicznie.

Składnia

template <class T>
class shared_ptr;

Uwagi

Klasa shared_ptr opisuje obiekt, który używa zliczania odwołań do zarządzania zasobami. shared_ptr Obiekt skutecznie przechowuje wskaźnik do zasobu, którego jest właścicielem lub zawiera wskaźnik o wartości null. Zasób może być własnością więcej niż jednego shared_ptr obiektu; gdy ostatni shared_ptr obiekt, który jest właścicielem określonego zasobu, zostanie zwolniony.

Element shared_ptr zatrzymuje posiadanie zasobu po ponownym przypisywaniu lub resetowaniu.

Argument T szablonu może być niekompletnym typem z wyjątkiem określonych funkcji składowych.

shared_ptr<T> Gdy obiekt jest konstruowany ze wskaźnika zasobu typu G* lub z shared_ptr<G>klasy , typ G* wskaźnika musi być konwertowany na T*. Jeśli nie jest konwertowany, kod nie zostanie skompilowany. Przykład:

#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>

Obiekt shared_ptr jest właścicielem zasobu:

  • jeśli został skonstruowany z wskaźnikiem do tego zasobu,

  • jeśli został skonstruowany z obiektu, który jest właścicielem shared_ptr tego zasobu,

  • jeśli został skonstruowany z obiektu wskazującego weak_ptr ten zasób, lub

  • jeśli do niego przypisano własność tego zasobu, za pomocą shared_ptr::operator= polecenia lub przez wywołanie funkcji shared_ptr::resetskładowej .

Obiekty shared_ptr , które są właścicielem zasobu, współużytkuje blok kontrolny. Blok kontrolny zawiera następujące blokady:

  • liczba shared_ptr obiektów, które są właścicielem zasobu,

  • liczba weak_ptr obiektów wskazujących zasób,

  • element usuwający dla tego zasobu, jeśli go ma,

  • alokator niestandardowy dla bloku kontrolnego, jeśli ma go.

shared_ptr Obiekt zainicjowany przy użyciu wskaźnika o wartości null ma blok kontrolny i nie jest pusty. shared_ptr Gdy obiekt zwolni zasób, nie jest już właścicielem tego zasobu. weak_ptr Gdy obiekt zwolni zasób, nie wskazuje już tego zasobu.

Gdy liczba shared_ptr obiektów, które są właścicielem zasobu, staje się zero, zasób jest zwalniany, usuwając go lub przekazując jego adres do usuwania, w zależności od tego, jak pierwotnie utworzono własność zasobu. Jeśli liczba shared_ptr obiektów, które są właścicielem zasobu, wynosi zero, a liczba weak_ptr obiektów wskazujących ten zasób wynosi zero, blok kontrolny jest zwalniany przy użyciu niestandardowego alokatora dla bloku kontrolnego, jeśli ma jeden.

shared_ptr Pusty obiekt nie jest właścicielem żadnych zasobów i nie ma bloku kontrolnego.

Deleter to obiekt funkcji, który ma funkcję operator()składową . Jego typ musi być konstruowalny, a jego konstruktor kopiujący i destruktor nie mogą zgłaszać wyjątków. Akceptuje jeden parametr, który ma zostać usunięty.

Niektóre funkcje przyjmują listę argumentów, która definiuje właściwości wynikowego shared_ptr<T> obiektu lub weak_ptr<T> . Taką listę argumentów można określić na kilka sposobów:

brak argumentów: wynikowy obiekt jest pustym shared_ptr obiektem lub pustym weak_ptr obiektem.

ptr: wskaźnik typu Other* do zasobu, który ma być zarządzany. T musi być kompletnym typem. Jeśli funkcja nie powiedzie się (ponieważ nie można przydzielić bloku kontrolnego), oblicza wyrażenie delete ptr.

ptr, deleter: wskaźnik typu Other* do zasobu, który ma być zarządzany, i usuwanie dla tego zasobu. Jeśli funkcja nie powiedzie się (ponieważ nie można przydzielić bloku sterowania), wywołuje deleter(ptr)metodę , która musi być dobrze zdefiniowana.

ptr, deleter, alloc: wskaźnik typu Other* do zasobu, który ma być zarządzany, usuwanie dla tego zasobu i alokator do zarządzania dowolnym magazynem, który musi zostać przydzielony i zwolniony. Jeśli funkcja nie powiedzie się (ponieważ nie można przydzielić bloku sterowania), wywołuje deleter(ptr)metodę , która musi być dobrze zdefiniowana.

spshared_ptr<Other>: obiekt, który jest właścicielem zasobu do zarządzania.

wpweak_ptr<Other>: obiekt wskazujący zasób do zarządzania.

apauto_ptr<Other>: obiekt, który zawiera wskaźnik do zasobu, który ma być zarządzany. Jeśli funkcja powiedzie się, wywołuje ap.release()metodę ; w przeciwnym razie pozostanie ap niezmieniona.

We wszystkich przypadkach typ Other* wskaźnika musi być konwertowany na T*wartość .

Bezpieczeństwo wątku

Wiele wątków może odczytywać i zapisywać różne shared_ptr obiekty w tym samym czasie, nawet jeśli obiekty są kopiami współwłaścicieli.

Członkowie

Nazwa/nazwisko opis
Konstruktory
shared_ptr Tworzy element shared_ptr.
~shared_ptr Niszczy element shared_ptr.
Definicje typów
element_type Typ elementu.
weak_type Typ słabego wskaźnika do elementu.
Funkcje składowe
get Pobiera adres zasobu należącego do firmy.
owner_before Zwraca wartość true, jeśli jest to shared_ptr uporządkowane przed (lub mniejszym) podanym wskaźnikiem.
reset Zastąp zasób własności.
swap Zamienia dwa shared_ptr obiekty.
unique Sprawdza, czy zasób należący do użytkownika jest unikatowy.
use_count Zlicza liczbę właścicieli zasobów.
Operatory
operator bool Sprawdza, czy istnieje zasób należący do użytkownika.
operator* Pobiera wyznaczoną wartość.
operator= Zastępuje należący do niego zasób.
operator-> Pobiera wskaźnik do wyznaczonej wartości.

element_type

Typ elementu.

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

Uwagi

Typ element_type jest synonimem parametru Tszablonu .

Przykład

// 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

Pobiera adres zasobu należącego do firmy.

element_type* get() const noexcept;

Uwagi

Funkcja składowa zwraca adres zasobu należącego do użytkownika. Jeśli obiekt nie jest właścicielem zasobu, zwraca wartość 0.

Przykład

// 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

Sprawdza, czy istnieje zasób należący do użytkownika.

explicit operator bool() const noexcept;

Uwagi

Operator zwraca wartość true , gdy get() != nullptr, w przeciwnym razie false.

Przykład

// 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*

Pobiera wyznaczoną wartość.

T& operator*() const noexcept;

Uwagi

Operator pośredni zwraca wartość *get(). W związku z tym przechowywany wskaźnik nie może mieć wartości null.

Przykład

// 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=

Zastępuje należący do niego zasób.

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
Wskaźnik udostępniony do skopiowania lub przeniesienia z.

ap
Wskaźnik automatyczny do przeniesienia. Przeciążenie auto_ptr jest przestarzałe w języku C++11 i usunięte w języku C++17.

up
Unikatowy wskaźnik obiektu do przyjęcia własności. up nie jest właścicielem obiektu po wywołaniu.

Other
Typ obiektu wskazywanego przez sp, aplub up.

Deleter
Typ usuwania obiektu należącego do niego, przechowywany do późniejszego usunięcia obiektu.

Uwagi

Operatory wszystkie dekrementują liczbę odwołań dla zasobu, który jest obecnie własnością *this zasobu, i przypisują własność zasobu o nazwie przez sekwencję operand do *this. Jeśli liczba odwołań spadnie do zera, zasób zostanie zwolniony. Jeśli operator ulegnie awarii, pozostanie *this niezmieniony.

Przykład

// 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->

Pobiera wskaźnik do wyznaczonej wartości.

T* operator->() const noexcept;

Uwagi

Operator zaznaczenia zwraca wartość get(), tak aby wyrażenie sp->member zachowywało się tak samo jak (sp.get())->member w przypadku obiektu sp klasy shared_ptr<T>. W związku z tym przechowywany wskaźnik nie może mieć wartości null i T musi być klasą, strukturą lub typem unii z składową member.

Przykład

// 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

Zwraca wartość true, jeśli jest to shared_ptr uporządkowane przed (lub mniejszym) podanym wskaźnikiem.

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
Odwołanie lvalue do elementu lub shared_ptrweak_ptr.

Uwagi

Funkcja składowa szablonu zwraca wartość true, jeśli *this jest uporządkowana przed ptr.

reset

Zastąp zasób własności.

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 kontrolowany przez wskaźnik argumentu.

Deleter
Typ usuwania.

ptr
Wskaźnik do skopiowania.

deleter
Usuwanie do skopiowania.

Allocator
Typ alokatora.

alloc
Alokator do skopiowania.

Uwagi

Operatory wszystkie dekrementują liczbę odwołań dla zasobu, który jest obecnie własnością *this zasobu, i przypisują własność zasobu o nazwie przez sekwencję operand do *this. Jeśli liczba odwołań spadnie do zera, zasób zostanie zwolniony. Jeśli operator ulegnie awarii, pozostanie *this niezmieniony.

Przykład

// 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

Tworzy element 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 kontrolowany przez wskaźnik argumentu.

ptr
Wskaźnik do skopiowania.

Deleter
Typ usuwania.

Allocator
Typ alokatora.

deleter
Usuwanie.

alloc
Alokator.

sp
Inteligentny wskaźnik do skopiowania.

wp
Słaby wskaźnik.

ap
Wskaźnik automatyczny do skopiowania.

Uwagi

Konstruktory każdy konstruuje obiekt, który jest właścicielem zasobu o nazwie przez sekwencję operandów. Konstruktor shared_ptr(const weak_ptr<Other>& wp) zgłasza obiekt wyjątku typu bad_weak_ptr , jeśli wp.expired().

Przykład

// 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

Niszczy element shared_ptr.

~shared_ptr();

Uwagi

Destruktor dekretor dekrementuje liczbę odwołań dla zasobu, który jest obecnie własnością elementu *this. Jeśli liczba odwołań spadnie do zera, zasób zostanie zwolniony.

Przykład

// 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

Zamienia dwa shared_ptr obiekty.

void swap(shared_ptr& sp) noexcept;

Parametry

sp
Wskaźnik udostępniony do zamiany.

Uwagi

Funkcja składowa pozostawia zasób pierwotnie należący do *thisspelementu , a zasób pierwotnie należący do sp*thisklasy . Funkcja nie zmienia liczby odwołań dla dwóch zasobów i nie zgłasza żadnych wyjątków.

Przykład

// 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

Sprawdza, czy zasób należący do użytkownika jest unikatowy. Ta funkcja została uznana za przestarzałą w języku C++17 i usunięta w języku C++20.

bool unique() const noexcept;

Uwagi

Funkcja składowa zwraca true wartość , jeśli żaden inny shared_ptr obiekt nie jest właścicielem zasobu, który jest własnością *thisobiektu , w przeciwnym razie false.

Przykład

// 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

Zlicza liczbę właścicieli zasobów.

long use_count() const noexcept;

Uwagi

Funkcja składowa zwraca liczbę shared_ptr obiektów będących właścicielem zasobu należącego do *thiselementu .

Przykład

// 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 słabego wskaźnika do elementu.

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

Uwagi

Definicja weak_type została dodana w języku C++17.

Zobacz też

Odwołanie do plików nagłówka
<memory>
unique_ptr
Klasa weak_ptr