c++ 智能指针 (std::weak_ptr)(三)

定义于头文件

template< class T > class weak_ptr;    (C++11 起) 

std::weak_ptr 是一种智能指针,它对被 std::shared_ptr 管理的对象存在非拥有性(「弱」)引用。在访问所引用的对象前必须先转换为 std::shared_ptr。

std::weak_ptr 用来表达临时所有权的概念:当某个对象只有存在时才需要被访问,而且随时可能被他人删除时,可以使用 std::weak_ptr 来跟踪该对象。需要获得临时所有权时,则将其转换为 std::shared_ptr,此时如果原来的 std::shared_ptr 被销毁,则该对象的生命期将被延长至这个临时的 std::shared_ptr 同样被销毁为止。

std::weak_ptr 的另一用法是打断 std::shared_ptr 所管理的对象组成的环状引用。若这种环被孤立(例如无指向环中的外部共享指针),则 shared_ptr 引用计数无法抵达零,而内存被泄露。能令环中的指针之一为弱指针以避免此情况。

创建管理被引用的对象的shared_ptr

std::weak_ptr::lock
std::shared_ptr lock() const noexcept;   (C++11 起) 

创建新的 std::shared_ptr 对象,它共享被管理对象的所有权。若无被管理对象,即 *this 为空,则返回亦为空的 shared_ptr

等效地返回 expired() ? shared_ptr() : shared_ptr(*this) ,原子地执行。

参数

(无)

返回值

若 std::weak_ptr::expired 返回 false 则为共享被占有对象所有权的 shared_ptr 。否则返回默认构造的 T 类型的 shared_ptr

注意

此函数和 std::shared_ptr 的构造函数可能获得 std::weak_ptr 所指向的被管理对象的临时所有权。区别是 std::shared_ptr 的构造函数在其 std::weak_ptr 为空时抛异常,而 std::weak_ptr::lock() 构造空的 std::shared_ptr

调用示例

#include 
#include 

void observe(std::weak_ptr weak)
{
    if (auto observe = weak.lock())
    {
        std::cout << "\tobserve() able to lock weak_ptr<>, value=" << *observe << "\n";
    }
    else
    {
        std::cout << "\tobserve() unable to lock weak_ptr<>\n";
    }
}

int main()
{
    std::weak_ptr weak;
    std::cout << "weak_ptr<> not yet initialized\n";
    observe(weak);

    {
        auto shared = std::make_shared(42);
        weak = shared;
        std::cout << "weak_ptr<> initialized with shared_ptr.\n";
        observe(weak);
    }

    std::cout << "shared_ptr<> has been destructed due to scope exit.\n";
    observe(weak);
}

输出

c++ 智能指针 (std::weak_ptr)(三)_第1张图片

提供弱指针的基于拥有者顺序

std::weak_ptr::owner_before
template< class Y >
bool owner_before( const weak_ptr& other) const noexcept;
   
template< class Y >
bool owner_before( const std::shared_ptr& other) const noexcept; 

以实现定义的基于拥有者(与基于值相反)顺序,检查此 weak_ptr 是否先于 other 。二个智能指针仅若都占有同一对象或均为空才比较相等,即使由 get() 获得的指针不同(例如因为它们指向同一对象中的不同子对象)。

此顺序用于令共享和弱指针可用作关联容器中的关键,通常经由 std::owner_less 。

参数

other - 要比较的 std::shared_ptr 或 std::weak_ptr

返回值

若 *this 前于 other 则为 true ,否则为 false 。常见实现比较控制块的地址。

调用示例

#include 
#include 

struct Foo
{
    int n1;
    int n2;
    Foo(int a, int b) : n1(a), n2(b) {}
};
int main()
{
    auto p1 = std::make_shared(1, 2);
    std::shared_ptr p2(p1, &p1->n1);
    std::shared_ptr p3(p1, &p1->n2);

    std::cout << std::boolalpha
              << "p2 < p3 " << (p2 < p3) << '\n'
              << "p3 < p2 " << (p3 < p2) << '\n'
              << "p2.owner_before(p3) " << p2.owner_before(p3) << '\n'
              << "p3.owner_before(p2) " << p3.owner_before(p2) << '\n';

    std::weak_ptr w2(p2);
    std::weak_ptr w3(p3);
    std::cout
            << "w2.owner_before(w3) " << w2.owner_before(w3) << '\n'
            << "w3.owner_before(w2) " << w3.owner_before(w2) << '\n';

    auto p5 = std::make_shared(6);
    std::weak_ptr w5(p5);
    std::cout
            << "w2.owner_before(w5) " << w2.owner_before(w5) << '\n'
            << "w5.owner_before(w2) " << w5.owner_before(w2) << '\n';
}

输出

c++ 智能指针 (std::weak_ptr)(三)_第2张图片

为weak_ptr赋值

std::weak_ptr::operator=

weak_ptr& operator=( const weak_ptr& r ) noexcept;

(1) (C++11 起)

template< class Y >
weak_ptr& operator=( const weak_ptr& r ) noexcept;

(2) (C++11 起)

template< class Y >
weak_ptr& operator=( const shared_ptr& r ) noexcept;

(3) (C++11 起)

weak_ptr& operator=( weak_ptr&& r ) noexcept;

(4) (C++14 起)

template< class Y >
weak_ptr& operator=( weak_ptr&& r ) noexcept;

(5) (C++14 起)

r 所管理者替换被管理对象。与 r 共享该对象。若 r 不管理对象,则 *this 亦不管理对象。

1-3) 等价于 std::weak_ptr(r).swap(*this) 。

4,5) 等价于 std::weak_ptr(std::move(r)).swap(*this) 。

参数

r - 与之共享对象的智能指针

返回值

*this

注意

实现应满足要求而不创建临时的 weak_ptr 对象。

你可能感兴趣的:(C++11新特性,c++,智能指针,weak_ptr)