前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于Singleton

关于Singleton

作者头像
逍遥剑客
发布2018-05-23 15:52:40
6950
发布2018-05-23 15:52:40
举报

这东西可能每个引擎里都有吧, 不管它是宏还是模板.

用宏的人可能觉得模板编译慢, 另外不想多继承

用模板的人可以觉得宏丑陋, 不利于调试

不管哪种方式, 个人觉得这个东西总比全局变量好

这里说说几种常见的情况:

  • 最简单的
    • 这是一种偷懒的做法, 访问时自动创建
template <class T>  
class Singleton  
{  
public:  
 static T* GetInstance()  
    {  
 static T singleton;  
 return &singleton;  
    }  
};  
  • 考虑抽象类的
    • 手动创建和销毁, 所以也能用于抽象类
template <class T>  
class Singleton  
{  
private:  
 static T *s_pSingleton;  
public:  
    Singleton()  
    {  
        assert(NULL == s_pSingleton);  
        s_pSingleton = static_cast<T*>(this);  
    }  
    ~Singleton()  
    {  
        assert(NULL != s_pSingleton);  
        s_pSingleton = NULL;  
    }  
 static T* GetInstance()  
    {   
 return s_pSingleton;  
    }  
};  
template <class T> T* Singleton<T>::s_pSingleton = NULL;  
  • 考虑线程安全的
    • 有时候我们想让Singleton只在一个模块内部使用, 而这个模块一般是处于自己的线程内部
    • 线程局部的好处一方面是安全, 另一方面可以针对不同的线程创建不同的singleton, 如主线程和渲染线程使用不同的IO系统
#define ThreadLocal __declspec(thread) 
template <class T>  
class Singleton  
{  
private:  
    ThreadLocal static T *s_pSingleton;  
public:  
    Singleton()  
    {  
        assert(NULL == s_pSingleton);  
        s_pSingleton = static_cast<T*>(this);  
    }  
    ~Singleton()  
    {  
        assert(NULL != s_pSingleton);  
        s_pSingleton = NULL;  
    }  
 static T* GetInstance()  
    {   
 return s_pSingleton;  
    }  
};  
template <class T> T* Singleton<T>::s_pSingleton = NULL;  
  • 考虑线程安全+DLL导出的
    • MSDN上说了, 要在DLL的环境下使用thread local的变量, 需要使用TlsAlloc系列函数
class ThreadLocalIndex  
{  
public:  
    ThreadLocalIndex()  
    {  
        m_tlsIndex = TlsAlloc();  
    }  
    ~ThreadLocalIndex()  
    {  
        TlsFree(m_tlsIndex);  
    }  
    operator DWORD() const 
    {  
 return m_tlsIndex;  
    }  
private:  
 DWORD m_tlsIndex;  
};  
template <class T>  
class Singleton  
{  
private:  
 static DWORD GetThreadLocalIndex()  
    {  
 static ThreadLocalIndex index;  
 return index;  
    };  
public:  
    Singleton()  
    {  
        assert(NULL == GetInstance());  
        TlsSetValue(GetThreadLocalIndex(), static_cast<T*>(this));  
    }  
    ~Singleton()  
    {  
        assert(NULL != GetInstance());  
        TlsSetValue(GetThreadLocalIndex(), NULL);  
    }  
 static T* GetInstance()  
    {   
 return (T*)TlsGetValue(GetThreadLocalIndex());  
    }  
};  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011年03月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档