之前的一篇单例模式帖子:https://blog.csdn.net/weixin_41318405/article/details/84586957
这次探讨懒汉模式细节问题。
先来看一段代码
class Data
{
public:
Data()
{
std::cout << this << "Data()\n";
}
~Data()
{
std::cout << this <<"~Data()\n";
}
};
int main()
{
Data *d1 = new Data;
Data d2;
delete d1;
return 0;
}
打印结果
从上述结果可以看出:(1)类对象指针在new的时候调用构造函数,但是程序结束不会自动销毁调用析构函数,需要用户手动调用析构函数。(2)类对象在定义会调用构造函数,程序结束会自动调用析构函数
说了这么多,这些到底对懒汉模式有什么用呢?
接下来看单例模式之懒汉模式,先上代码
class Singleton
{
public:
static Singleton* GetInstance()
{
//此处两层判断,为了就是提高效率
//此处使用到了锁,为了就是保证线程安全(同步和互斥)
/*if (nullptr == m_pInstance)
{
m_pInstance = new Singleton;
}*/
if (nullptr == m_pInstance)
{
m_tex.lock();
if (nullptr == m_pInstance)
{
m_pInstance = new Singleton;
}
m_tex.unlock();
}
return m_pInstance;
}
//定义一个内部类。程序结束回收对象,因为是new申请了空间
class cycle
{
public:
~cycle()
{
if (m_pInstance != nullptr)
{
delete m_pInstance;
m_pInstance = nullptr;
}
}
private:
//定义一个静态回收类对象
static cycle endflag;
};
Singleton(const Singleton& s) = delete;
Singleton operator=(Singleton& s) = delete;
private:
Singleton(){}
static Singleton *m_pInstance;//单例对象指针
static mutex m_tex;
};
Singleton* Singleton::m_pInstance = nullptr;
mutex Singleton::m_tex;
Singleton::cycle Singleton::cycle::endflag;
void fun(int n)
{
cout << Singleton::GetInstance() << endl;
}
int main()
{
thread t1(fun, 1);
thread t2(fun, 2);
thread t3(fun, 3);
t1.join();
t2.join();
t3.join();
return 0;
}
1. 此处没有使用单例模式的析构函数释放m_pInstance,而是使用了一个内部回收类?
如果使用单例模式Singleton的析构函数delete m_pInstance,因为delete释放的是自定义类型,所以导致循环调用析构函数,最终造成栈溢出。
2. 单例对象本质来时一个类对象指针,所以它的释放权利已经交给了用户,但是现在用户也不能通过调用析构函数释放了。
因为类对象(不是类对象指针)在程序结束自动调用析构函数,所以使用这一思想,通过创建一个静态的内部类对象,在其析构函数内销毁单例对象指针,这样就不会导致内存泄漏。