osg.Referenced
是 OpenSceneGraph 中所有引用计数对象的基类。引用计数对象是指其生命周期由多个引用对象共同管理,通过增减引用计数来控制对象的释放时机。
class OSG_EXPORT Referenced: public Object
{
//...
}
其中,Object
为 OSG 中所有对象的基类,包含了一些基础的功能和接口。
osg.Referenced
中的引用计数机制是通过两个主要的成员变量来实现的:
AtomicInt _refCount; // 引用计数
bool _deleteOnZeroRefCount; // 引用计数在降为 0 时是否自动销毁对象
其中,_refCount
是一个原子计数器对象,可以确保多线程环境下的并发修改安全;_deleteOnZeroRefCount
标记了当对象的引用计数减为 0 时,是否自动销毁对象。
引用计数的增减分别通过以下接口实现:
void osg::Referenced::ref() const // 引用计数增加
bool osg::Referenced::unref() const // 引用计数减少,如果引用计数为 0 则自动销毁对象
int osg::Referenced::referenceCount() const // 返回当前对象的引用计数
其中,ref()
操作应当在获取该对象的“读取”引用时调用;而 unref()
操作应当在释放该对象的引用时调用。如需在单线程环境下处理引用计数,可以根据实际情况直接使用 referenceCount()
接口对引用计数进行监控。
为了使用引用计数机制,所有 osg.Referenced
的子类需要重载 cloneType()
和 clone()
接口。
virtual Object* cloneType() const { return new MyClass(); }
virtual Object* clone(const CopyOp&) const { return new MyClass(*this); }
cloneType()
必须返回一个“相同类型的新对象”的实例,而 clone()
则必须返回一个“完全拷贝自身”的实例,其中 CopyOp
为拷贝操作的附加参数,用于确定拷贝的深度和方式等。
由于引用计数机制的存在,当多个对象互相关联时,应当避免循环引用,以免导致内存泄漏。(如 A 引用 B,B 又反向引用了 A)
osg.Referenced
不会对其成员变量进行自动的引用计数管理。因此,当成员变量是引用计数类型时,需要在对象的构造器和析构器中添加相应的 ref()
和 unref()
操作。(or 在构造函数中使用递归调用进行参考计数的递归处理)