单例应该这样写

来源:互联网 发布:mysql更改语句 编辑:程序博客网 时间:2024/04/29 22:38

Code First:

CIndexManager *CIndexManager::s_instance;boost::mutex CIndexManager::s_mutex;CIndexManager::CGarbo CIndexManager::s_garbo;CIndexManager *CIndexManager::GetInstance(){    if (s_instance == NULL)    {        boost::mutex::scoped_lock lock(s_mutex);        if (s_instance == NULL)        {            s_instance = new CIndexManager();        }    }    return s_instance;}

特点:

1. Lazy Initilization , 当单例不被使用时不会被初始化;

2. Double Check, 两次判空的用意是,在对性能要求较高的时候,直接加锁会形成瓶颈,初始化之后,每次只需判空即能判断是否初始化过;

不足之处是,没有翻译语句,所以可以在类内部加上,

class CIndexManager {        static boost::mutex s_mutex;    static CIndexManager *s_instance;    static CIndexManager *GetInstance();    class CGarbo    {    public:        ~CGarbo()        {            if (s_instance != NULL)            {                delete s_instance;            }        }    };    static CGarbo s_garbo;};

这样,s_garbo 在释放时就可以翻译单例了,一个小的包装类来完成释放工作!

当然有人会说,并行时,有可能 s_instance 先被赋值,构造函数后被调用,有一定的风险,当然 VC 上暂时没发现这种特例,如果你高兴,也可以加上原子操作屏障来阻止这类事情的发生,这里不谈。


Over !

2 0