侵入式智能指针的参考计数器
Reference counter for intrusive 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;
我的问题如下:
为什么要使用friend
关键字?为什么不声明函数 public?
为什么使用volative
关键字?编译器在哪里以及为什么可以积极优化这个值?或者这个关键字只是作为预防措施使用的?
作为奖励,为什么以前的方法(已注释掉)被现有代码取代?是不是之前的方法出了什么问题,是错误还是特殊情况没有按预期工作?
非常感谢。
函数被标记为 friend
以便它们可以编辑 class 的 m_refCount
成员变量,即使它是私有的并且函数不是 [=18= 的一部分]本身。
volatile
关键字及其使用 __sync_
函数的原因是允许此实现在不使用互斥锁的情况下在多线程环境中工作。
以下是一位不再与我们合作的同事编写的代码摘录。我对为什么以这种方式而不是其他方式编写此代码有疑问。我对这位同事的印象非常好,他是为数不多的能够在脑子里编译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;
我的问题如下:
为什么要使用
friend
关键字?为什么不声明函数 public?为什么使用
volative
关键字?编译器在哪里以及为什么可以积极优化这个值?或者这个关键字只是作为预防措施使用的?
作为奖励,为什么以前的方法(已注释掉)被现有代码取代?是不是之前的方法出了什么问题,是错误还是特殊情况没有按预期工作?
非常感谢。
函数被标记为 friend
以便它们可以编辑 class 的 m_refCount
成员变量,即使它是私有的并且函数不是 [=18= 的一部分]本身。
volatile
关键字及其使用 __sync_
函数的原因是允许此实现在不使用互斥锁的情况下在多线程环境中工作。