如何实现std :: tr1 :: shared_ptr? [英] How is the std::tr1::shared_ptr implemented?
问题描述
我一直在想使用共享指针,我知道如何实现一个自己 - 不想这样做,所以我试着 std :: tr1 :: shared_ptr
,我有几个问题...
I've been thinking about using shared pointers, and I know how to implement one myself--Don't want to do it, so I'm trying std::tr1::shared_ptr
,and I have couple of questions...
如何实现参考计数?它使用双向链表吗? (Btw,我已经google了,但我找不到任何可靠的。)
How is the reference counting implemented? Does it use a doubly linked list? (Btw, I've already googled, but I can't find anything reliable.)
使用 std :: tr1 :: shared_ptr
?
推荐答案
shared_ptr
shared_ptr
must manage a reference counter and the carrying of a deleter functor that is deduced by the type of the object given at initialization.
shared_ptr <>必须管理引用计数器并携带由初始化时提供的对象类型推导出的删除函子。 / code>类通常包含两个成员:
T *
(由 operator->
并在 operator *
中取消引用)和 aux *
其中 aux
是一个包含以下内容的内部抽象类:
The shared_ptr
class typically hosts two members: a T*
(that is returned by operator->
and dereferenced in operator*
) and a aux*
where aux
is a inner abstract class that contains:
- 计数器(在拷贝分配/销毁时递增/递减)
- 需要增加/减少原子(不需要是特定平台原子INC / DEC可用)
- 一个抽象
virtual destroy 0;
- 一个虚拟析构函数。
- a counter (incremented / decremented upon copy-assign / destroy)
- what needed to make increment / decrement atomic (not needed is specific platform atomic INC/DEC are available)
- an abstract
virtual destroy()=0;
- a virtual destructor.
c $ c> aux 类(实际名称取决于实现)由一个模板化类族(由显式构造函数给出的类型参数化)来导出,例如 U
源自 T
),添加:
such aux
class (the actual name depends on the implementation) is derived by a family of templatized classes (parametrized on the type given by the explicit constructor, say U
derived from T
), that add:
- a指向该对象的指针(与
T *
相同,但具有实际类型:这是正确管理T
作为在派生层次结构中具有多个T
的任何U
的基础) - 将作为删除策略的
deletor
对象的副本提供给显式构造函数(或默认deletor
做删除p
,其中p
是上面的U *
) - 调用destroyter函子覆盖destroy方法。
- a pointer to the object (same as
T*
, but with the actual type: this is needed to properly manage all the cases ofT
being a base for whateverU
having multipleT
in the derivation hierarchy) - a copy of the
deletor
object given as deletion policy to the explicit constructor (or the defaultdeletor
just doing deletep
, wherep
is theU*
above) - the override of the destroy method, calling the deleter functor.
可以是这一个:
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) interloked_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; }
};
其中 weak_ptr
需要互操作性( weak_count
)需要在 aux
中(将递增/递减code> weak_ptr )和 delete pa
必须在两个计数器都达到零时发生。
Where weak_ptr
interoperability is required a second counter (weak_count
) is required in aux
(will be incremented / decremented by weak_ptr
), and delete pa
must happen only when both the counters reach zero.
这篇关于如何实现std :: tr1 :: shared_ptr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!