C++实现单例模式时的销毁问题,在线等~~~
再讲到单例模式的销毁时,在网上看到以下一段话:
我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利用这个特征,我们可以在C++单例模式类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。如下面的代码中的CGarbo类(Garbo意为垃圾工人):
class CSingleton:
{
// 其它成员
public:
static CSingleton * GetInstance(){。。。}
private:
CSingleton(){};
static CSingleton * m_pInstance;
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if (CSingleton::m_pInstance)
delete CSingleton::m_pInstance;
}
};
static CGarbo Garbo; // 定义一个静态成员,在程序结束时,系统会调用它的析构函数
}
类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其它地方滥用。
在程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。
使用这种方法释放单例对象有以下特征:
1.在单例类内部定义专有的嵌套类。
2.在单例类内定义私有的专门用于释放的静态成员。
3.利用程序在结束时析构全局变量的特性,选择最终的释放时机。
4.使用C++单例模式的代码不需要任何操作,不必关心对象的释放。
我就不明白了,这样销毁单例,有什么意义?求指导。
[解决办法]
1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。
2、利用静态局部对象的单例模式:
static A& getInstance()
{
static A a;
return a;
}
[解决办法]
谢谢你的回答。让我受益匪浅,我接着有如下疑问,你说到:静态对象和全局对象都会在程序结束时被系统负责析构。在程序结束时,在程序结束时,会释放该程序占用的所有资源。还有必要认为去控制内存的释放吗?
再强调一下:
至于意义嘛,你new的指针,你不负责释放你不觉得过分么?这是良好,安全的编程习惯。
你的类里简单,就是开辟了点内存,退出就销毁了,是无所谓,但是如果稍微复杂点呢?和硬件建立了个连接没有关闭?锁定了系统的资源没有解锁?没有给服务器发退出消息?你觉得合理么?
[解决办法]
这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?
1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。
2、利用静态局部对象的单例模式:static A& getInstance()
{
static A a;
return a;
}
智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。
有引用计数的智能指针是共享型的,当共享计数为0时自动释放。
a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么?
这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object
[解决办法]
这样是所谓的RAll机制自动销毁,也可以定义一个静态函数释放单实例指针,但需要你记得调用它。还有的实现方法是在静态函数内定义静态局部对象。
谢谢你的回答,对于所谓的RAll机制自动销毁和在静态函数内定义静态局部对象,有一些不清楚?能否进行说明一下?拜托了。在静态函数内定义静态局部对象是什么机制?
1、RAll机制:利用c++的构造与析构特性自动回收资源,智能指针就属于这一类,还有自动关闭句柄等。
2、利用静态局部对象的单例模式:static A& getInstance()
{
static A a;
return a;
}
智能指针,不是使用的引用计数么?这个a貌似没有被释放。我个人认为。如果有不对的地方,请指正,拜托了。
有引用计数的智能指针是共享型的,当共享计数为0时自动释放。
a为什么没有被释放?你觉得这个静态对象的析构函数不会被调用吗?为什么?
这里有些讨论:http://stackoverflow.com/questions/1463707/c-singleton-vs-global-static-object/*
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton *GetInstance()
{
if (m_Instance == NULL)
{
m_Instance = new Singleton();
}
return m_Instance;
}
int GetTest()
{
return m_Test;
}
private:
Singleton(){ m_Test = 10; }
static Singleton *m_Instance;
int m_Test;
// This is important
class GC
{
public:
~GC()
{
// We can destory all the resouce here, eg:db connector, file handle and so on
if (m_Instance != NULL)
{
cout<<"Call the GC's destructor"<<endl;
delete m_Instance;
m_Instance = NULL;
}
}
};
static GC gc;
};
Singleton *Singleton::m_Instance = NULL;
int main(int argc, char *argv[])
{
Singleton *singletonObj = Singleton::GetInstance();
cout<<singletonObj->GetTest()<<endl;
return 0;
}
谢谢你推荐的文章,但是,这个是个demo,那么cout<<"Call the GC's destructor"<<endl;会执行的,但是实际上,这个语句没有被执行;拜托解释一下。谢谢了。
你推荐的文章中,有人提到以下实现是最好的单例实现:Printer & thePrinter() {
static Printer printer;
return printer;
}
但是,这种单例实现在实际应用中会遇到对象的拷贝问题,你有遇到过吗?
如果修改成以下是否可以:Printer *thePrinter() {
static Printer printer;
return &printer;
}
希望能得到你的指导,谢谢。再次谢谢你耐心的指导。
推荐使用只有三行代码的这种实现方式。这种方式在Qt的源码中也很常见。我一般都这样使用。
至于修改为返回指针,同样阻止不了复制行为,想想为什么?
要阻止复制行为,声明拷贝构造函数、赋值函数为私有即可。对于单例模式,由于不允许直接构造,因此构造函数也是私有的。