【问题标题】:Will this Singleton Class Automatically Release Memory upon Destruction?这个单例类会在销毁时自动释放内存吗?
【发布时间】:2013-02-21 02:22:48
【问题描述】:

我创建了一个单例类,我想知道我的析构函数是否会自动为名为@9​​87654321@ 的静态变量释放内存。

下面的代码会自动释放内存吗?

class SingletonClass
{
    SingletonClass() 
    {

    }

    ~SingletonClass()
    {
       delete this; // or should I say... delete instance;
    }

    public:

    static SingletonClass* instance;

    SingletonClass* getInstance()
    {
       if (instance != NULL)
          return instance;

       instance = new SingletonClass();
       return instance;
    }
};

PS: 是否可以只使instance 成为常​​规的单例变量而不是指针?这会是更好的代码实践吗?

【问题讨论】:

  • 你认为这个析构函数到底什么时候会被调用?
  • @us2012 我认为当变量超出范围和/或应用程序(.exe)结束时会调用它。
  • @VaughnCato 抱歉打错字了,应该是指针
  • @VaughnCato 是的,对不起,另一个错字

标签: c++ memory-management singleton raii


【解决方案1】:

这个单例类在你的程序中愉快地注入Undefined Behavior

您有一个具有自动存储功能的static 成员变量。作为一个全局变量,它将在你的main() 例程进入之前被构造,并在你的main() 例程退出之后被破坏。

因此,一旦你的程序终止并退出main()函数,你的SingletonClass实例的析构函数就会被调用,它会尝试delete this;但是,该对象不是通过调用new 分配的,并且对不是通过new 分配的对象调用delete 会产生未定义的行为。

您可以安全地删除delete this 指令:当您的程序终止时,全局对象会自动销毁。

编辑:

在对您的问题进行编辑后,曾经是 SingletonClass 类型的 static 变量变成了 static 类型 SingletonClass* 的变量。我建议你改回来:

static SingletonClass instance;

SingletonClass* getInstance()
{
    return &instance;
}

实际上,instance 可以(并且可能应该)甚至是函数getInstance()static 局部变量:

SingletonClass* getInstance()
{
    static SingletonClass instance;
    return &instance;
}

这样,您甚至不必为static 类成员变量提供全局定义

或者,您可以使用智能指针来处理对象的生命周期,但这在此处是不必要的。只需将该变量声明为getInstance()static 局部变量即可。在 C++11 中,它的初始化也将保证是线程安全的

【讨论】:

  • 如果我从函数中删除delete this;,我不会有我请求但从未归还的内存吗?
  • @JakeM:不。只有当您通过调用new 获得内存时才会出现这种情况。在这里,您有一个全局变量,当您的程序终止时它会自动销毁。简短的故事是:你没有通过new分配它,所以你不应该通过delete释放它。
  • @JakeM:哦等等:全局变量是指针?然后我必须编辑我的答案。
  • 实例的类型为static Singleton* 而不是static Singleton,这是一个错字。所以 afaik 它是通过调用函数 getInstance() 中的 new 来分配的
  • @JakeM: 好的,那么在这种情况下它应该是deleted,是的,但不在类的析构函数中(析构函数被称为之后 delete ),所以如果你在析构函数中,一定有人已经调用了delete。此时,调用delete this 将释放对象两次。
【解决方案2】:

像使用智能指针一样

 static std::unique_ptr<SingletonClass> instance;

它会在程序终止时为您删除实例。避免在代码成员中使用delete this,除非您真的知道自己在做什么以及后果是什么。

【讨论】:

    猜你喜欢
    • 2013-07-06
    • 2012-07-15
    • 2016-05-07
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    相关资源
    最近更新 更多