侵入式智能指针的参考计数器

时间:2016-02-24 19:49:47

标签: c++ boost smart-pointers

以下是由不再与我们合作的同事撰写的代码摘录。我有问题为什么这个代码是用这种方式编写的,而不是任何其他代码。我对这位同事的印象非常好,他是少数能够编写C ++代码的人之一。

#include <boost/smart_ptr.hpp>

namespace boost
{

/*****************************************
class RefCounter
{
protected:
    RefCounter() : m_refCount(0) {}
    virtual ~RefCounter() { }

private:
    friend void intrusive_ptr_release(RefCounter * p);
    friend void intrusive_ptr_add_ref(RefCounter * p);

    volatile long m_refCount;

    virtual void incRef() {__sync_add_and_fetch(&m_refCount, 1);}
    virtual void decRef() {if (__sync_sub_and_fetch(&m_refCount, 1) == 0) delete this;}
};

inline void intrusive_ptr_add_ref(RefCounter * p)
{
    p->incRef();
}

inline void intrusive_ptr_release(RefCounter * p)
{
    p->decRef();
}
************************************************/

class RefCounter
{
protected:
    RefCounter() : m_refCount(0) {}
    RefCounter(const RefCounter&) : m_refCount(0) {}
    virtual ~RefCounter() {}

    long getRefCount() const {return m_refCount;}

private:
    friend void intrusive_ptr_release(RefCounter * p);
    friend void intrusive_ptr_add_ref(RefCounter * p);
    volatile long m_refCount;
};

inline void intrusive_ptr_add_ref(RefCounter * p)
{
    __sync_add_and_fetch(&p->m_refCount, 1);
}

inline void intrusive_ptr_release(RefCounter * p)
{
    if (__sync_sub_and_fetch(&p->m_refCount, 1) == 0) delete p;
}

} // namespace boost

使用示例:

struct Foo : public boost::RefCounter
{
    int a;
};

typedef boost::intrusive_ptr<Foo> FooIntrusivePtr;
FooIntrusivePtr fooPtr;

我的问题如下:

  1. 为什么要使用friend个关键字?为什么不将这些函数公开?

  2. 为什么要使用volative关键字?编译器在何处以及为何可以积极地优化此值?或者此关键字仅用作预防措施?

  3. 作为奖励,为什么先前的方法(已注释掉)被现有代码取代?以前的方法出了什么问题,错误或特殊情况没有按预期工作?

    非常感谢。

1 个答案:

答案 0 :(得分:3)

这些函数被标记为friend,因此它们可以编辑类的m_refCount成员变量,即使它是私有的,并且函数不是类本身的一部分。

volatile关键字及其使用__sync_函数的原因是允许此实现在不使用互斥锁的情况下在多线程环境中工作。