如何删除单例对象
Posted
技术标签:
【中文标题】如何删除单例对象【英文标题】:how to delete singleton object 【发布时间】:2013-03-21 22:32:46 【问题描述】:假设这个实现是单例模式(当然我们应该避免单例:这只是个问题),我一直在考虑创建静态对象。它是由new
运算符在堆上创建的,当然,但是它是如何被销毁的呢?在下面的例子中我们有一个泄漏,那么应该如何实现静态单例对象的删除?是否应该采用please_delete()
公共接口,所以可以调用myC->please_delete()
或者有其他方法可以实现吗?
class CC
public:
static CC* cObj()
if(c_ptr==NULL)
c_ptr=new CC();
return c_ptr;
else return c_ptr;
int getValue()return value_;
void setValue(int val)value_=val;
~CC()cout<<"~CC";
private:
CC():value_(12345)cout<<"CC";
static CC* c_ptr;
int value_;
;
// Allocating and initializing CC's
// static data member. The pointer is being
// allocated - not the object itself.
CC *CC::c_ptr = 0;
int main()
//Singleton pattern
CC* myC = CC::cObj();
cout<<myC->getValue();
return 0;
输出:CC12345
运行成功(总时间:67 毫秒)
我注意到我们确实可以像boost::shared_ptr<CC> bCptr(CC::cObj());
一样在shared_ptr
中声明单例静态实例,但是单例模式根本没有提到删除对象的问题,所以也许还有其他方法?
【问题讨论】:
单身人士喜欢这样吗?为什么不直接返回static CC
?
我似乎错过了为 c_ptr 分配 CC 对象的行
是的,当然,改变了,谢谢
【参考方案1】:
Singleton 设计模式的一部分是它是坚不可摧的。
编辑:
关于可破坏性,有 2 种单例:
-
可破坏(应用程序破坏时它们会死)
坚不可摧(当机器损坏时它们会死)
无论哪种方式,如果构建正确,一旦创建了单例实例,它就会保留下来。这是对 Singleton 设计模式的主要批评之一。
这里有一些解决模式可破坏性方面的参考资料。
http://nicolabonelli.wordpress.com/2009/06/04/singleton-a-mirage-of-perfection/ http://www10.informatik.uni-erlangen.de/Teaching/Courses/SS2009/CPP/altmann.pdf http://sourcemaking.com/design_patterns/singleton http://sourcemaking.com/design_patterns/to_kill_a_singleton
【讨论】:
我完全同意。让我们在航天器.stackexchage.com 上提出这个问题 它是如何坚不可摧的?它不应该被称为然后泄漏吗?但是,其他应用程序仍然可以使用它吗? 如果单例泄漏,则不适合用作航天器材料。 单子实际上并没有泄漏,因为它们会牢牢固定在原位,直到整个航天器或应用程序被破坏。 谢谢,现在我明白了宇宙飞船和单例删除【参考方案2】:经典的单例模式没有描述删除方面。
但是,如果我必须这样做,我会从一个简单的方法开始,如下所示(它不是万无一失的):
1) 类似于创建/检索单例对象的静态方法,比如createObject()
,还有一个用于破坏单例对象的静态方法,比如destructObject()
2) 有一个计数器,用于统计系统中当前对象的数量;
从 0 开始 在createObject()
调用时,递增1
在deleteObject()
调用时,它减1。
如果达到 0,则调用 delete
以实际上破坏对象
【讨论】:
与 shared_ptr 的唯一区别是计数器是全局的(在系统中不是使用此单例的单个应用程序)对吗? 计数器也像实际对象一样是单例的。【参考方案3】:我不喜欢使用指针。
class Single
private:
Single();
public:
Single& Instance()
static Single the_instance;
Return the_instance;
;
这个单例将从调用Instance()
直到应用程序退出并执行静态对象的销毁。在这种情况下,将调用单例对象的析构函数。
实际上,即使在原始示例中使用指针时,操作系统也会在应用程序退出时回收内存。但是在这种情况下,对象的析构函数将不会被调用。
【讨论】:
以上是关于如何删除单例对象的主要内容,如果未能解决你的问题,请参考以下文章