C++ 如何删除单例指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8699434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:00:31  来源:igfitidea点击:

How to delete Singleton pointer?

c++singleton

提问by Atul

I was implementing a singleton pattern.Here,I am creating a new instance of Singleton* in GetInstance, when I try and delete it in the destructor, it does in infinite loop. How to avoid memory leak in this case ?

我正在实现一个单例模式。在这里,我在 GetInstance 中创建了一个 Singleton* 的新实例,当我尝试在析构函数中删除它时,它会在无限循环中执行。在这种情况下如何避免内存泄漏?

Please refer the below piece of code:

请参考以下代码:

#define NULL 0
class Singleton  
{ 
    private :  
        static Singleton* m_pInstance;  
        Singleton(){};  

    public :

    static Singleton* GetInstance()
    {
        if(m_pInstance == NULL)
        {
            m_pInstance  = new Singleton();         
        }
        return m_pInstance;
    }

    ~Singleton()
    { 
        //delete m_pInstance; // The system goes in infinate loop here if i uncomment this  
        m_pInstance = NULL;
    }
};

Singleton*  Singleton ::m_pInstance = NULL;   

int main()  
{
    Singleton* pInstance = Singleton::GetInstance();
    delete pInstance;  
}     

回答by Offirmo

Of course it causes an infinite loop !

当然会导致无限循环!

You call the destructor, but the destructor also calls the destructor, so the destructor calls the destructor again... and again...

你调用析构函数,但析构函数也调用析构函数,所以析构函数再次调用析构函数……一次又一次……

If you want to use delete, you must use it from outsideof the destructor and NOT call it again in the destructor.

如果要使用delete,则必须从析构函数外部使用它,而不要在析构函数中再次调用它。

To do that, you can use another static method which will mirror the GetInstance()method :

为此,您可以使用另一个静态方法来镜像该GetInstance()方法:

class Singleton  
{ 
public :

   ...

   // this method is a mirror of GetInstance
   static void ResetInstance()
   {
      delete m_pInstance; // REM : it works even if the pointer is NULL (does nothing then)
      m_pInstance = NULL; // so GetInstance will still work.
   }

   ...

   ~Singleton()
   { 
       // do destructor stuff : free allocated resources if any.
       ...
   }

Note : the other people warn you about using a singleton and they are right because this pattern is often misused. So think before using it. But go ahead anyway, that is the good way to learn !

注意:其他人警告你不要使用单例,他们是对的,因为这种模式经常被误用。所以使用前请三思。但无论如何,这是学习的好方法!

回答by thiton

While the best practice is not using the singleton pattern in most cases, it is good practice to use static local variables in functions to create singletons:

虽然在大多数情况下最好的做法是不使用单例模式,但在函数中使用静态局部变量来创建单例是一种很好的做法:

static Singleton& Singleton::GetInstance() {
     static Singleton the_singleton;
     return the_singleton; 
}

To give some rationale to the best practice: Singleton-nage is usually unnecessary unless you have to represent a truly global resource. Singletons suffer from all the drawbacks of global variables (because they are global variables with some OO icing), and often have little justification in being truly singular. The naive programmer might want to implement Godas a singleton object. The wise programmer doesn't and rejoices when the customer turns out to be a polytheist.

为最佳实践提供一些基本原理:除非您必须表示真正的全局资源,否则通常不需要 Singleton-nage。单例遭受全局变量的所有缺点(因为它们是带有一些面向对象的全局变量),并且通常没有理由成为真正的单例。天真的程序员可能希望实现God为单例对象。聪明的程序员不会,并且会为客户变成多神论者而欢欣鼓舞。

回答by Paul Manta

Here's a more correct implementation of singletons:

这是单例更正确的实现:

class Singleton
{
  public:
    static Singleton& Instance()
    {
        static Singleton inst;
        return inst;
    }

  protected:
    Singleton(); // Prevent construction
    Singleton(const Singleton&); // Prevent construction by copying
    Singleton& operator=(const Singleton&); // Prevent assignment
    ~Singleton(); // Prevent unwanted destruction
};

The static instance gets created the first time you call Instance()and destroyed when the program closes.

静态实例在您第一次调用Instance()时创建,并在程序关闭时销毁。

But beware about using singletons. They are not evil, as some here think the are (I find that position irrational), but they are very easy to misuse and hard to use correctly. As a rule of thumb, don't use singletons for your "interface classes" (the ones that are used by other parts of the program); try to use singletons only as implementation details and only when it feels appropriate.

但要注意使用单例。它们并不像这里的一些人认为的那样邪恶(我认为这种立场是不合理的),但是它们很容易被误用并且很难正确使用。根据经验,不要在“接口类”(程序其他部分使用的那些)中使用单例;尝试仅将单例用作实现细节,并且仅在感觉合适时使用。



Edit:A usage example

编辑:使用示例

Some time ago I posted an answer on gamedev.stackexchange and the solution I proposed made use of singletons as part of the implementation, not the interface. The code is commented and explains why singletons are needed: https://gamedev.stackexchange.com/a/17759/6188

前段时间我在 gamedev.stackexchange 上发布了一个答案,我提出的解决方案使用单例作为实现的一部分,而不是接口。代码注释并解释了为什么需要单例:https: //gamedev.stackexchange.com/a/17759/6188

回答by Alessandro Pezzato

Add a static member Singleton::DestroyInstance()that delete the instance and call it from the main.

添加一个静态成员Singleton::DestroyInstance(),删除实例并从主调用它。

void Singleton::DestroyInstance() {
    delete m_pInstance;
    m_pInstance = 0;
}

/* ...................... */

int main()  
{
    Singleton* pInstance = Singleton::GetInstance();
    /* ... */
    Singleton::DestroyInstance();    
}  

回答by wilx

Short answer, do not use singletons.

简短的回答,不要使用单身人士。

Longer answer, never call delete on the singleton pointer in main(). Use some sort of static object that will delete the singleton when other global variables dtors are being called.

更长的答案,永远不要在main(). 使用某种静态对象将在调用其他全局变量 dtors 时删除单例。

回答by rich

using SingletonHolder of Loki-Library written by Andrei Alexandrescu.

使用由 Andrei Alexandrescu 编写的 Loki-Library 的 SingletonHolder。

#include "SingletonHolder"

class Singleton
{
//not allowed ctor
private:
   Singleton()
   {}

   ~Singleton()
   {}

   ...

   //Singelton on heap
   friend struct Loki::CreateUsingNew<Singleton>;
}

Singleton& get_singleton_pointer()
{
   return Loki::SingltonHolder<Singleton>::Instance();
}

In this example the Singlton will be deleted while programm was ended. There is also some other stategie to create singleton pointer using malloc, static... more detail take a look of: http://loki-lib.sourceforge.net/html/a00628.html

在这个例子中,Singlton 将在程序结束时被删除。还有一些其他的 stategie 使用 malloc 创建单例指针,静态......更多细节看看:http: //loki-lib.sourceforge.net/html/a00628.html

Alternativ you can create singleton just using a static variable:

或者,您可以仅使用静态变量创建单例:

template <typename T>
struct CreateUsingStatic
{
   static T& get_T_singleton()
   {
      static T t;
      return t;
   }
};

class Singleton
{
   ...
private:
   friend struct CreateUsingStatic<Singleton>;
}