侵入式智能指针的引用计数器

Reference counter for intrusive smart pointers

本文关键字:引用 计数器 指针 智能      更新时间:2023-10-16

以下是一位不再与我们合作的同事编写的代码摘录。我有疑问为什么以这种方式而不是任何其他方式编写此代码。我对这位同事的印象非常好,他是少数几个能够在脑海中编译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关键字?编译器可以在何处以及为什么积极优化此值?或者这个关键字只是作为一种预防措施?

作为奖励,为什么以前的方法(注释掉)被现有代码替换?以前的方法是否有问题,错误或特殊情况无法按预期工作?

非常感谢。

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

volatile关键字以及它使用 __sync_ 函数的原因是允许此实现在多线程环境中工作,而无需使用互斥锁。