打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
weak_ptr 类模板

weak_ptr 类模板

Introduction 简介
Synopsis 概要
Members 成员
Free Functions 自由函数
Frequently Asked Questions 常见问题

Introduction 简介

weak_ptr 类模板存储一个引向已被 shared_ptr 管理的对象的 "weak reference"(弱引用)。为了访问这个对象,一个 weak_ptr 可以利用 shared_ptr 的构造函数或成员函数 lock 转换为 shared_ptr。当最后一个指向对象的 shared_ptr 消失,而对象也被删除后,从一个引向已被删除对象的 weak_ptr 实例获取 shared_ptr 的企图就会失败:构造函数会抛出一个 boost::bad_weak_ptr 类型的异常,而 weak_ptr::lock 会返回一个 empty shared_ptr

每一个 weak_ptr 都符合 C++ 标准库的 CopyConstructibleAssignable 的必要条件,并因此能够用于标准库容器。因为提供了比较操作,因此 weak_ptr 可以和标准库中的关联式容器一起工作。

weak_ptr 的操作绝不会抛出异常。

这个类模板被 T 参数化,T 是被指向的对象的类型。

相对于 shared_ptrweak_ptr 提供了一个非常有限的操作子集,因为在多线程程序中访问它所存储的指针是非常危险的,甚至有时在一个单线程程序中也是不安全的(也就是说,它可能引起未定义行为)。姑且假设 weak_ptr 有一个返回 raw pointer(裸指针)的 get 成员函数,考虑下面这个无辜的代码片段:

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

// some time later

if(int * r = q.get())
{
// use *r
}

设想在 if 之后,但是又恰恰在 r 被使用之前,另一个线程执行了语句 p.reset()。这样 r 就成了一个 dangling pointer(悬挂指针)。

解决这个问题的方案是从 q 创建一个临时的 shared_ptr

shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);

// some time later

if(shared_ptr<int> r = q.lock())
{
// use *r
}

这样,r 就持有一个引向 q 所指向的对象的引用。即使在其它线程中执行了 p.reset(),那个对象也会继续活着,直到 r 离开作用域或者被 reset。通过获得一个指向这个对象的 shared_ptr,我们可以有效地保住它不被析构。

Synopsis 概要

namespace boost {

template<class T> class weak_ptr {

public:
typedef T element_type;

weak_ptr();

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

~weak_ptr();

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

long use_count() const;
bool expired() const;
shared_ptr<T> lock() const;

void reset();
void swap(weak_ptr<T> & b);
};

template<class T, class U>
bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b);

template<class T>
void swap(weak_ptr<T> & a, weak_ptr<T> & b);
}

Members 成员

element_type 元素类型

typedef T element_type;

提供模板参数 T 的类型。

constructors 构造函数

weak_ptr();

作用:构造一个 empty weak_ptr

后置条件:use_count() == 0

抛出:无。

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

作用:如果 rempty,构造一个 empty weak_ptr,否则,构造一个和 r shares ownership(共享所有权)的 weak_ptr,就像存储了 r 中所存储指针的一个拷贝。

后置条件:use_count() == r.use_count()

抛出:无。

destructor 析构函数

~weak_ptr();

作用:销毁这个 weak_ptr,但对于所存储指针所指向的对象没有作用。

抛出:无。

assignment 赋值

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

作用:等价于 weak_ptr(r).swap(*this)

抛出:无。

注意:实现可以自由地经由不同的手段达到其效果(以及隐含的保证),而不创建临时变量。

use_count 使用计数

long use_count() const;

返回:如果 *thisempty,返回 0,否则,返回和 *this share ownership(共享所有权)的 shared_ptr 对象的数目。

抛出:无。

注意:use_count() 达不到必要的效率。只用于调试和测试的目的。而不要用于产品代码。

expired 过期

bool expired() const;

返回:use_count() == 0

抛出:无。

注意:expired() 可能比 use_count() 更快。

lock 锁

shared_ptr<T> lock() const;

返回:expired()? shared_ptr<T>(): shared_ptr<T>(*this)

抛出:无。

reset 重置

void reset();

作用:等价于 weak_ptr().swap(*this)

swap 交换

void swap(weak_ptr & b);

作用:交换两个智能指针的内容。

抛出:无。

Free Functions 自由函数

comparison 比较

template<class T, class U>
bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b);

返回:一个未确定值,以致于

  • operator< 是一个严格意义上的 C++ 标准 25.3 [lib.alg.sorting] 中描述的 weak ordering(弱顺序);
  • 等值关系通过 operator< 来定义,!(a < b) && !(b < a),在这种情况下,当且仅当两个 weak_ptr 实例 share ownership(共享所有权)或者都为 empty 时,两个 weak_ptr 相等。

抛出:无。

注意:允许 weak_ptr 对象在关联式容器中作为键值使用。

swap 交换

template<class T>
void swap(weak_ptr<T> & a, weak_ptr<T> & b)

作用:等价于 a.swap(b)

抛出:无。

注意:std::swap 的接口匹配。为泛型编程提供帮助。

Frequently Asked Questions 常见问题

问:一个对象能不能在自己的构造函数内创建一个指向自己的 weak_ptr 呢?

答:不能。weak_ptr 只能从一个 shared_ptr 创建,而在对象构造的时候指向对象的 shared_ptr 还不存在。即使你能创建一个指向 this 的临时 shared_ptr,它也会在构造函数结尾处离开作用域,而所有的 weak_ptr 实例立马过期。

解决方案是把构造函数做成 private 的,并配备一个返回 shared_ptr 的工厂函数。

class X
{
private:

X();

public:

static shared_ptr<X> create()
{
shared_ptr<X> px(new X);
// create weak pointers from px here
return px;
}
};
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
shared_ptr
C 智能指针的底层实现原理
Boost智能指针
源码分析shared_ptr实现
C++11智能指针
C++ 对象生命周期管理
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服