zoukankan      html  css  js  c++  java
  • Mitsuba中的智能指针ref<>和scheduler单例

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

    先说说class ref, 它在includemitsubacore ef.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的对象。

    多么巧妙的设计!

  • 相关阅读:
    SQL Server 查看新建、重建、重组索引进度
    CentOS PostgreSQL 12 主从复制(主从切换)
    CentOS PostgreSQL 12 安装
    SQL Server 当前事务无法提交,而且无法支持写入日志文件的操作。
    MySQL 碎片整理
    MySQL 5.7 MHA(mha4mysql-manager依赖包)
    MySQL- 5.7 sys schema
    MySQL InnoDB 恢复(recovery)详细流程
    MySQL学习(二十五)order by 逻辑
    jvm学习(一)DirectByteBuffer堆外内存浅析
  • 原文地址:https://www.cnblogs.com/wangpei0522/p/4554909.html
Copyright © 2011-2022 走看看