设计模式:单例模式(C++)

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;        
}

参考:

https://blog.csdn.net/Hackbuteer1/article/details/7460019

https://blog.csdn.net/stpeace/article/details/46564309

猜你喜欢

转载自www.cnblogs.com/Younger-Zhang/p/12653131.html