共用方式為


shared_ptr 類別

將參考計數的智慧型指標環繞動態配置物件。

語法

template <class T>
class shared_ptr;

備註

類別 shared_ptr 描述使用參考計數來管理資源的 物件。 shared_ptr物件實際上存放了它擁有之資源的指標,或是存放 null 指標。 資源可以由多個 shared_ptr 物件擁有;當擁有特定資源的最後一個 shared_ptr 物件終結時,會釋放資源。

shared_ptr在重新指派或重設資源時,停止擁有資源。

樣板引數 T 可能是不完整的類型,針對特定成員函式註明者除外。

shared_ptr<T> 物件是從 G* 類型的資源指標或是從shared_ptr<G>建構時,指標類型 G* 必須可轉換為 T*。 如果無法轉換,程式碼將不會編譯。 例如:

#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 物件在下列情況下會擁有資源:

  • 如果它是使用該資源的指標建構,

  • 如果它是從擁有該資源的 shared_ptr 物件建構,

  • 如果它是從 weak_ptr 指向該資源的 物件建構,則為 ,或

  • 如果已將該資源的擁有權指派給該資源,請使用 shared_ptr::operator= 或 呼叫成員函式 shared_ptr::reset

擁有資源的 shared_ptr 物件也會共用控制區塊。 控制區塊會存放:

  • 擁有資源的 shared_ptr 物件數目、

  • 指向資源的 weak_ptr 物件數目、

  • 如果有的話,該資源的刪除者、

  • 如果有的話,控制區塊的自訂配置器。

shared_ptr使用 Null 指標初始化的物件具有控制項區塊,而且不是空的。 在 shared_ptr 物件釋放資源之後,它不再擁有該資源。 在 weak_ptr 物件釋放資源之後,它不再指向該資源。

當擁有資源的 shared_ptr 物件數目變成零時,會藉由刪除資源或將資源的位址傳遞至刪除者來釋放資源,視原先建立資源擁有權的方式而定。 當擁有資源的 shared_ptr 物件數目為零,且指向該資源的 weak_ptr物件為零時,會使用控制區塊的自訂配置器來釋放控制區塊,如果有的話。

空白 shared_ptr 物件不會擁有任何資源,而且沒有控制區塊。

刪除者是具有成員函式 operator() 的函式物件。 它的類型必須是可複製建構,且其複製建構函式和解構函式不能擲回例外狀況。 它接受一個參數,也就是要刪除的物件。

有些函式接受引數清單,其中定義所產生之 shared_ptr<T>weak_ptr<T> 物件的內容。 您可以透過數種方法指定這類引數清單:

無引數:產生的物件是空白 shared_ptr 物件或空白 weak_ptr 物件。

ptr:要管理之資源的型別 Other* 指標。 T 必須是完整的類型。 如果函式失敗(因為無法配置控制區塊),它會評估運算式 delete ptr

ptr, deleter:要管理之資源的型 Other* 別指標,以及該資源的刪除器。 如果函式失敗(因為無法配置控制區塊),它會呼叫 deleter(ptr) ,這必須妥善定義。

ptr, deleter, alloc:要管理之資源的型 Other* 別指標、該資源的刪除程式,以及配置器來管理必須配置和釋放的任何儲存體。 如果函式失敗(因為無法配置控制區塊),它會呼叫 deleter(ptr) ,這必須妥善定義。

spshared_ptr<Other>:擁有要管理之資源的 物件。

wpweak_ptr<Other>:指向要管理之資源的 物件。

apauto_ptr<Other>:物件,保留要管理之資源的指標。 如果函式成功,則會呼叫 ap.release() ,否則會保持不變 ap

在所有情況下,指標類型 Other* 必須可轉換為 T*

執行緒安全性

多個執行緒可以同時讀取和寫入不同的 shared_ptr 物件,即使物件是共用擁有權的複本時也是一樣。

成員

名稱 描述
建構函式
shared_ptr 建構 shared_ptr
~shared_ptr 終結 shared_ptr
Typedefs
element_type 元素的類型。
weak_type 專案弱式指標的類型。
成員函式
get 取得擁有的資源位址。
owner_before 如果這個 shared_ptr 排序在所提供的指標之前 (或小於),則傳回 true。
reset 取代所擁有的資源。
swap 交換兩個 shared_ptr 物件。
unique 測試擁有的資源是否唯一。
use_count 計算資源擁有者的數目。
運算子
operator bool 測試擁有的資源是否存在。
operator* 取得指定的值。
operator= 取代所擁有的資源。
operator-> 取得指定值的指標。

element_type

元素的類型。

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

備註

element_type 類型與樣板參數 T 同義。

範例

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

取得擁有的資源位址。

element_type* get() const noexcept;

備註

此成員函式會傳回所擁有資源的位址。 如果物件沒有資源,則會傳回 0。

範例

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

測試擁有的資源是否存在。

explicit operator bool() const noexcept;

備註

當 時 get() != nullptr ,運算子會傳回 的值 true ,否則 false 為 。

範例

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

取得指定的值。

T& operator*() const noexcept;

備註

間接取值運算子會傳回 *get()。 因此,儲存的指標不得為 Null。

範例

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

取代所擁有的資源。

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);

參數

sp
要複製或移動的共用指標。

ap
要移動的自動指標。 多 auto_ptr 載在 C++11 中已被取代,並在 C++17 中移除。

up
要採用 擁有權之 物件的唯一指標。 up 在呼叫之後,不會擁有任何 物件。

Other
apupsp 指向之 物件的型別。

Deleter
所擁有物件的刪除程式類型,儲存以供稍後刪除物件。

備註

這些運算子都會遞減 *this 目前所擁有之資源的參考計數,並將運算元序列所命名的資源擁有權指派給 *this。 如果參考計數降為零,即會釋放資源。 如果運算子失敗,則會維持 *this 不變。

範例

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

取得指定值的指標。

T* operator->() const noexcept;

備註

選取運算子會傳回 get(),如此一來,運算式 sp->member 的運作方式會與 (sp.get())->member 相同,其中 sp 是類別 shared_ptr<T> 的物件。 因此,儲存的指標不得為 null,而且 T 必須是含有 member 成員的類別、結構或等位類型。

範例

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

如果這個 shared_ptr 排序在所提供的指標之前 (或小於),則傳回 true。

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;

參數

ptr
weak_ptr 的左值參考 shared_ptr

備註

如果 *this 是在 之前 ptr 排序,則樣板成員函式會傳回 true。

reset

取代所擁有的資源。

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);

參數

Other
引數指標所控制的類型。

Deleter
刪除者的類型。

ptr
要複製的指標。

deleter
要複製的刪除者。

Allocator
配置器的類型。

alloc
要複製的配置器。

備註

這些運算子都會遞減 *this 目前所擁有之資源的參考計數,並將運算元序列所命名的資源擁有權指派給 *this。 如果參考計數降為零,即會釋放資源。 如果運算子失敗,則會維持 *this 不變。

範例

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

建構 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;

參數

Other
引數指標所控制的類型。

ptr
要複製的指標。

Deleter
刪除者的類型。

Allocator
配置器的類型。

deleter
刪除者。

alloc
配置器。

sp
要複製的智慧型指標。

wp
弱式指標。

ap
要複製的自動指標。

備註

每個建構函式都會建構擁有由運算元序列所命名之資源的物件。 如果 wp.expired() ,建構 shared_ptr(const weak_ptr<Other>& wp) 函式會擲回 類型的 bad_weak_ptr 例外狀況物件。

範例

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

終結 shared_ptr

~shared_ptr();

備註

解構函式會遞減 *this 目前所擁有之資源的參考計數。 如果參考計數降為零,即會釋放資源。

範例

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

交換兩個 shared_ptr 物件。

void swap(shared_ptr& sp) noexcept;

參數

sp
要交換的共用指標。

備註

成員函式會保留原先由 *this 擁有且後續由 sp 擁有的資源,以及原先由 sp 擁有且後續由 *this 擁有的資源。 函式不會變更兩個資源的參考計數,也不會擲回任何例外狀況。

範例

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

測試擁有的資源是否唯一。 此函式在 C++17 中已被取代,並在 C++20 中移除。

bool unique() const noexcept;

備註

如果沒有其他 shared_ptr 物件擁有 *this 所擁有的資源,成員函式就會傳回 true,否則會傳回 false

範例

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

計算資源擁有者的數目。

long use_count() const noexcept;

備註

成員函式會傳回擁有 *this 所擁有之資源的 shared_ptr 物件數目。

範例

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

專案弱式指標的類型。

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

備註

定義 weak_type 已在 C++17 中新增。

另請參閱

標頭檔參考
<memory>
unique_ptr
weak_ptr 類別