shared_ptr
必须管理引用计数器和删除器函子的携带,该删除器函子是根据初始化时给定的对象类型推导出来的。
The shared_ptr
类通常容纳两个成员:T*
(由返回operator->
并取消引用operator*
) and a aux*
where aux
是一个内部抽象类,包含:
- 计数器(在复制分配/销毁时递增/递减)
- 使递增/递减原子化所需的任何内容(如果特定平台原子 INC/DEC 可用,则不需要)
- 摘要
virtual destroy()=0;
- 虚拟析构函数。
Such aux
类(实际名称取决于实现)由一系列模板化类派生(根据显式构造函数给出的类型进行参数化,例如U
源自T
),添加:
- 指向该对象的指针(与
T*
,但对于实际类型:这是正确管理所有情况所必需的T
成为任何事物的基础U
有多个T
在派生层次中)
- 的副本
deletor
对象作为显式构造函数的删除策略(或默认的deletor
刚刚删除p
, where p
is the U*
above)
- 重写 destroy 方法,调用删除器函子。
一个简化的草图可以是这样的:
template<class T>
class shared_ptr
{
struct aux
{
unsigned count;
aux() :count(1) {}
virtual void destroy()=0;
virtual ~aux() {} //must be polymorphic
};
template<class U, class Deleter>
struct auximpl: public aux
{
U* p;
Deleter d;
auximpl(U* pu, Deleter x) :p(pu), d(x) {}
virtual void destroy() { d(p); }
};
template<class U>
struct default_deleter
{
void operator()(U* p) const { delete p; }
};
aux* pa;
T* pt;
void inc() { if(pa) interlocked_inc(pa->count); }
void dec()
{
if(pa && !interlocked_dec(pa->count))
{ pa->destroy(); delete pa; }
}
public:
shared_ptr() :pa(), pt() {}
template<class U, class Deleter>
shared_ptr(U* pu, Deleter d) :pa(new auximpl<U,Deleter>(pu,d)), pt(pu) {}
template<class U>
explicit shared_ptr(U* pu) :pa(new auximpl<U,default_deleter<U> >(pu,default_deleter<U>())), pt(pu) {}
shared_ptr(const shared_ptr& s) :pa(s.pa), pt(s.pt) { inc(); }
template<class U>
shared_ptr(const shared_ptr<U>& s) :pa(s.pa), pt(s.pt) { inc(); }
~shared_ptr() { dec(); }
shared_ptr& operator=(const shared_ptr& s)
{
if(this!=&s)
{
dec();
pa = s.pa; pt=s.pt;
inc();
}
return *this;
}
T* operator->() const { return pt; }
T& operator*() const { return *pt; }
};
Where weak_ptr
互操作性需要第二个计数器(weak_count
)需要在aux
(将增加/减少weak_ptr
), and delete pa
仅当两个计数器都达到零时才会发生。