如何实现std :: tr1 :: shared_ptr? [英] How is the std::tr1::shared_ptr implemented?

查看:179
本文介绍了如何实现std :: tr1 :: shared_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在想使用共享指针,我知道如何实现一个自己 - 不想这样做,所以我试着 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 of T being a base for whatever U having multiple T in the derivation hierarchy)
  • a copy of the deletor object given as deletion policy to the explicit constructor (or the default deletor just doing delete p, where p is the U* 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆