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. Na 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, lubjeśli do niego przypisano własność tego zasobu, za pomocą
shared_ptr::operator=
polecenia lub przez wywołanie funkcjishared_ptr::reset
skł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.
sp
shared_ptr<Other>
: obiekt, który jest właścicielem zasobu do zarządzania.
wp
weak_ptr<Other>
: obiekt wskazujący zasób do zarządzania.
ap
auto_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ątkowe
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.
Elementy członkowskie
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 T
szablonu .
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
, ap
lub 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_ptr
weak_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 *this
sp
elementu , a zasób pierwotnie należący do sp
*this
klasy . 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ą *this
obiektu , 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 *this
elementu .
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