1. GetInstance()函数返回值为指针
为了防止拷贝出现,GetInstance()可以返回指针或者引用:
A *m_pA = A::GetInstance();
A &a = A::GetInstance();
返回引用,对调用时候的定义有一定的要求,不如直接返回指针方便;
万一调用者没有使用引用的方法,而是直接A a = A::GetInstance()调用,就是通过拷贝实现,和单例不符!
实际上,C++的单例模式一般都返回指针,所以为了通用性,GetInstance()需要返回指针!
2. static修饰GetInstance()函数
目的是为了“无对象调用”:A::GetInstance(),毕竟调用GetInstance()的时候,还没有对象创建出来。
3. 构造函数私有化
构造函数私有化,是为了让外界无法调用构造函数,但是GetInstance()函数肯定会调用构造函数的。
4. 如何析构?
普通对象在类外通过new创建,在类外通过delete删除,new的时候自动调用构造函数,delete的时候自动调用析构函数;
单例模式假如在构造函数中new,到底是先执行构造函数还是先执行new?都说不通!
同理,单例模式的delete也不可以在析构函数中执行,因为只有delete的时候才执行析构函数,而执行析构函数的时候又delete?
循环调用的结果表面上看是析构多次,但其实一次都没有完成!一直在调用函数的路上。
解决方法:
1. GetInstance()获得指针之后,delete指针;
2. 类似GetInstance()创建对象,也可以再定义一个函数比如,DeleteInstance()来直接delete对象。
缺点:两种方法都是手动调用delete,容易忘记
3. 内嵌类
内嵌一个新类,并在单例类中包含该新类的对象,而且是静态类型的;
系统退出的时候会自动删除该类的静态成员,该新类是静态类型,删除的时候调用新类的析构函数;
在新类的析构函数中delete单例模式的new指针,实现了自动delete!
5. 实现方法
单例模式可以使用new(每次判断是否为NULL),和局部静态变量static,两种方法实现;
前者需要考虑:线程安全问题(多个线程同时GetInstance(),如何保证只创建一个?),如何delete(只能增加内嵌类);
后者使用静态局部变量,在C++11之后,static已经是线程安全的了,而且系统自动释放资源,不用额外考虑delete;
综上,强烈推荐使用static实现单例模式!
static A* GetInstance() { static A a; return &a; }
参考: