Mitsuba中的智能指针ref<>和scheduler单例

本文深入探讨了Mitsuba中ref和scheduler的实现细节,阐述了它们如何协同工作以高效地管理资源。ref作为智能指针,负责堆上对象的生命周期管理;scheduler则作为单例类,确保资源的正确初始化与销毁,避免了内存泄漏和资源竞争的问题。文章详细解释了ref的构造、复制和析构过程,以及scheduler的静态初始化机制。

Mitsuba中随处可见ref<xxx> 和 scheduler

先说说class ref, 它在include\mitsuba\core\ref.h中定义

template<typename T>
class ref{
public:
    /// Create a NULL reference
    ref() : m_ptr(NULL) { }

    /// Construct a reference from a pointer
    ref(T *ptr) : m_ptr(ptr) { if (m_ptr) ((Object *) m_ptr)->incRef(); }

    /// Copy-constructor
    ref(const ref &pRef) : m_ptr(pRef.m_ptr) { if (m_ptr) ((Object *) m_ptr)->incRef(); }

    /// Destroy this reference
    ~ref() { if (m_ptr) ((Object *) m_ptr)->decRef(); }
.....
private:
T* m_ptr; };

ref的作用类似于我们常使用的智能指针,用来管理在堆上申请对象的资源释放。在前面的文章中(http://www.cnblogs.com/wangpei0522/p/4542223.html)谈了谈object基类限制对象只能在堆上申请,如此统一的采用ref来传递和释放资源。

上面的代码中,ref的析构函数~ref()只做了一个操作:m_ptr->decRef(),在object中,有一个成员

volatile mutable int m_refCount;

从字面意思就能读出它的作用:记录该对象被引用的次数。

每次ref的构造函数都调用incRef()把该对象的引用次数加一,而析构函数调用decRef()减一。一旦m_refCount==0,就调用该对象的析构函数(虚函数),释放它的资源。


scheduler是一个单例类,它的声明大概是这样的:

class scheduler{
public:
   inline static Scheduler* getInstance(){return m_scheduler;}
   static void staticInitialization();
protected:
   scheduler();
   ~scheduler();
private:
   static scheduler* m_scheduler;
};

staticInitialization()在main()中被调用,用于初始化m_scheduler指向的对象。(如果你对单例模式还不熟悉,请看:http://www.cnblogs.com/wangpei0522/p/4460529.html)

通过getInstance()将m_scheduler托管给ref<Scheduler>,同时Scheduler的构造函数和析构函数都设置为protected,不允许手动new/栈上创建对象,也不允许手动调用delete删除m_scheduler的对象。

多么巧妙的设计!

 

转载于:https://www.cnblogs.com/wangpei0522/p/4554909.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值