本文不讨论单例模式的具体定义
单例模式应该是面试问的最多的一个模式了,手写的概率很大。
Singleton表明程序运行时产生的对象只能是一个,那么只能从类内的构造函数进行考虑。
步骤:
1、将构造函数(默认构造、拷贝构造、赋值构造)放到私有处;
2、类内public声明一个静态的自身对象,当然你可以选择是对象或者是指针,指针的话需要自己手动释放内存,而无指针的对象编译器会在程序结束后帮你释放。(但是别作死把析构函数放到了private中);
3、类外初始化类内的静态成员变量,这里的初始化分两种,一种是饿汉式,直接new一个对象返回给该成员变量,第二种是懒汉式,先初始化为0,然后在类内进行判断是否new对象。这里的饿汉式是线程安全的,懒汉式是存在线程不安全的;
4、类内提供一个接口用来获取对象。
图片来自
先放代码再说需要注意的东西
#include#include #include using namespace std; namespace h1 { //单例模式,饿汉式 class Singleton { public: ~Singleton(){cout<<"xigou"< 第一需要注意的
首先说一下开头说的别作死把Singleton析构函数放到private中,如果放到private中,如果不是用new一个Singleton对象,编译器是会报错的,因为对于普通的栈内存的对象,作用域结束或者程序结束会释放栈内存,不用自己手动delete,没有内存泄露问题存在,而把析构放到私有,那么栈内存就不能自动的释放了,编译器就会报错。还有个问题就是析构函数设置为私有,new在堆区,在我们delete的时候才发现原来不可访问析构函数。所以千万别作死把析构函数弄成私有,要不然要检查好久的错误。
当然如果事情发生了,又想把析构函数放到private中(这样的应用场景就是对象只能在堆上使用内存),可以在类内public中声明一个内部类,内部类实现一个destroy函数接口delete当前的对象。这样的话就能正确释放内存了。
第二需要注意的
懒汉式的双检查锁真的是完美无缺了嘛?当然不是,听了李建忠老师的设计模式课程的同学可能比较清除。
双检查锁存在reorder问题。
正常的single = new Singleton;过程是先分配内存,然后调用构造函数最后赋值给single指针。
但是在指针级别可能会reorder,即先分配内存,再地址赋值给指针,然后调用构造函数,这样就会导致还没有调用构造函数有别的对象返回对象了,但是这个对象是没有经过构造函数的。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)