如何删除单例对象

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&lt;CC&gt; 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() 直到应用程序退出并执行静态对象的销毁。在这种情况下,将调用单例对象的析构函数。

实际上,即使在原始示例中使用指针时,操作系统也会在应用程序退出时回收内存。但是在这种情况下,对象的析构函数将不会被调用。

【讨论】:

以上是关于如何删除单例对象的主要内容,如果未能解决你的问题,请参考以下文章

如何删除jQuery对象中元素

如何删除jQuery对象中元素

JAVA中如何从ArrayList中删除重复对象

如果已删除,如何从向量中删除对象

如何从对象数组中删除对象。在淘汰赛JS。错误:对象不支持属性或方法“删除”

使用删除链接删除对象时如何包含 @Html.AntiForgeryToken()