单例类的私有析构函数

Kha*_*anS 9 c++ singleton

是否必须为单例类具有私有析构函数.

Pot*_*ter 14

如果单例在全局范围内实现为变量,则它必须具有公共析构函数.只有公共成员才能在全球范围内访问.

如果它在自己的类中声明为静态成员或静态本地,那么析构函数可能是私有的.析析程序从类范围内调用,在程序退出时可以访问它.这是强制对象成为单身人士的一种方法.你需要强烈执行吗?如果是的话,是的.这取决于你的意思是"强制性的".

class A{
private:
    ~A() {}
public:
    static A &getGlobalA() {
        static A a2; // <- or here - better technique
        return a2;   // this is initialized upon 1st access
    };               // and destroyed on program exit

    static A a; // <- constructor, destructor accessed from here
};

A A::a; // <- but "called" from here in terms of control flow
Run Code Online (Sandbox Code Playgroud)


Def*_*ult 7

这可能不是你想要的..但​​作为参考,我使用如下:

// .h
class Foo {
public:
    static Foo* getInstance();
    static void destroy();
private:
    Foo();
    ~Foo();

    static Foo* myInstance;
};

// .cpp
Foo* Foo::myInstance = NULL;

Foo* Foo::getInstance(){
    if (!myInstance){
        myInstance = new Foo();
    }
    return myInstance;
}
void Foo::destroy(){
    delete myInstance;
    myInstance = NULL;
}
Run Code Online (Sandbox Code Playgroud)

然后在我的程序结束时,我在对象上调用destroy.正如Péter所指出的那样,当你的程序结束时系统会回收内存,所以没有真正的理由.我使用销毁的原因是当Ogre抱怨我没有释放我分配的所有内存时.在那之后我只是用它作为"好的方式",因为我喜欢自己清理.

  • 问题是你正在打开泄漏的代码.singelton的用户必须知道他们需要使用销毁它然后在正确的位置插入代码.与Java不同,C++允许优秀的开发人员承担设计类的责任,因此很难滥用(RAII的一个特性).作为开发人员,您应该尝试使用此壁炉架并尝试构建一个不需要用户理解实现以正确使用它的singelton.要求明确的销毁是让用户有机会滥用该类(通过不调用它). (4认同)
  • 您可能想要使用atexit注册destroy. (2认同)

Mar*_*ers 5

所有的类都有一个析构函数。如果您不创建,编译器将为您创建。所以你的问题可以改写为:单例类的析构函数是否必须是私有的?

简单的答案是否定的,它不一定是。

一个更有趣的问题:将单例类的析构函数设为私有是个好主意吗?

是的,总的来说,这是一个好主意。如果您将其设为私有,那么您的客户端代码将不会意外调用析构函数。调用析构函数会导致所有客户端的单例失败,因为实例将变得无效。

  • @Travis:它可以:`GetSingleton()-&gt;~CSingleton()` (3认同)
  • 或者不那么反常:`p = GetSingleton()`,和`/* 妈妈告诉我总是删除我的指针:*/ delete p;` (3认同)

Vad*_*kov 5

在我看来,signleton 的析构函数应该是私有的。否则有人可以为您的单例实例调用“删除”。我知道,通常没有人会这样做。但如果我们谈论卓越的设计,它必须能够抵抗所有可能的有意或无意的损害。

使用现代 C++,甚至可以为静态构造的对象声明私有析构函数。这是我的单例代码片段:

class Singleton
{
public:
    static Singleton& GetInstance();

    // Before C++ 11 
private:
    Singleton()  {}
    ~Singleton() {}

    Singleton(const Singleton&);            // Without implementation
    Singleton& operator=(const Singleton&); // Without implementation

    // Since C++ 11
private:
    Singleton()  = default;
    ~Singleton() = default;

public:
    Singleton(const Singleton&)            = delete;
    Singleton& operator=(const Singleton&) = delete;
};

Singleton& Singleton::GetInstance()
{
    static Singleton instance;
    return instance;
}
Run Code Online (Sandbox Code Playgroud)