单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式,主要分为饿汉式和懒汉式,网上有许多资料。
blog.jobbole.com/108579
http://blog.csdn.net/woxiaohahaa/article/details/51344409
这里重点提几个需要注意的问题:
1.构造函数私有化
为了避免用户在任意地方生成实例
2.线程安全
线程安全问题只存在懒汉式单例模式中,主要是在GetInstance()中new对象之前使用锁,双检锁,局部变量过渡等方法实现线程安全,参考https://www.cnblogs.com/myd620/p/6133420.html
3.实例析构的时间点
实例为静态对象,在程序结束时析构;
但是资料上这么说“如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源(设断点调试了一下,确实没有进入singleton的析构函数),那么上面的代码无法实现这个要求。我们需要一种方法,正常的删除该实例”
(1)常规做法是在单例类里定义私有内嵌类CGarbo的静态私有对象Garbo,在私有内嵌类实现单例实例的析构。需要注意的是该私有内嵌类没有数据,因此该静态私有对象需要在类外部进行初始化,否者虽然编译不报错,但是该对象不会生成,则该对象相当于没有,参考https://yq.aliyun.com/wenzhang/show_70374
(2)另一种做法是声明实例的对象为getinstance()的静态局部变量,但需要考虑复制函数等,即:
class Singleton {
public:
static Singleton& getInstance(){
static Singleton instance;
return instance;
}
};
个人不太喜欢这种方法,但知乎上有人说这种方法是C++11标准单例类
(3)也可以直接用智能指针管理实例;
参考http://blog.csdn.net/realxie/article/details/7090493;
4.单例模式模板化(没有搜到认为太好的模板单例类资料,贴一个参考http://blog.csdn.net/kentzhang_/article/details/48206821)
为了实现程序复用,将单例类抽象成单例模板类。FreeNOS源码中也有单例模板类,但是里面过于简单,不推荐。需注意问题:
(1)基础知识点:模板类的类方法的定义和声明需要在同一个.h文件中,不能分开。详见c++primer plus
(2)作为模板类型的类的构造函数,析构函数设置为私有。
(3)在需要使用单例类模式的类中,用友元关键friend + class + 单例类模板的名字<当前类的名字>,将单例类模板声明为当前类的友元:
template<typename T>
friend class MySingleton;
(4)第3点析构问题的(1)用在模板类上,会出现一个问题:模板类的私有内嵌类CGarbo的内嵌静态私有对象Garbo的初始化问题,
若在外部初始化为
template<typename T>
MySingleton<T>::CGarbo MySingleton<T>::Garbo;
会出现如下错误:
error C2143: syntax error : missing ';' before 'MySingleton<T>::Garbo'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
fatal error C1903: unable to recover from previous error(s); stopping compilation
伪解决方法:
template<typename T> typename
MySingleton<T>::CGarbo MySingleton<T>::Garbo;
参考http://ask.csdn.net/questions/222830
添加typename只是编译通过了,但是并没有真正初始化,如3.(1)中所说该对象相当于没有。
我当前做法是使用具体初始化:
在testClass类的testClass.h文件的类外面初始化
MySingleton<testClass>::CGarbo MySingleton<testClass>::Garbo;
真正解决方法还没找到
总结(2).(3).(4)点,模板类型的testClass类,设计如下所示:
#include "MySingleton.h"
class testClass
{
private:
testClass(void);
~testClass(void);
private:
template<typename T>
friend class MySingleton;
};
MySingleton<testClass>::CGarbo MySingleton<testClass>::Garbo;
转载请注明出处
浙公网安备 33010602011771号