Singleton:有内存泄漏吗?

vla*_*don 6 c++ singleton memory-leaks

这是一个简单的单身人士:

class Singleton
{
    Singleton();
    virtual ~Singleton();

    Singleton * Singleton::getInstance() 
    {
        static Singleton * instance;

        if (!instance) {
            instance = new Singleton();
        };
        return instance;
    };
}
Run Code Online (Sandbox Code Playgroud)

当主代码Singleton::getInstance()->someMethod()第一次调用时,是不是实例化了两次类?会有内存泄漏吗?

我问,因为Visual Leak Detector检测到线路上的内存泄漏new Singleton().

Lig*_*ica 14

当主代码Singleton::getInstance()->someMethod()第一次调用时,是不是实例化了两次类?

不.调用静态成员Singleton不会实例化Singleton,因此Singleton这里存在的唯一实例是您创建的实例new.而你只创建一次,因为一旦instance指向它,你再也不会打电话new了.

但是,您遇到的一个问题是您无法创建getInstance静态成员函数.我认为这是一个错字/疏忽,否则,你的程序甚至不会编译.事实上,即使作为非静态成员,声明也是不正确的.此外,构造函数应该private强制执行只能getInstance实例化类型的概念.

会有内存泄漏吗?

是的,这就是Leak Detector报告的内容.但是,它是最小的:问题是delete在程序关闭之前没有任何单例实例.

坦率地说,我不担心.这可能是泄漏可接受的罕见时期之一,主要是因为不仅仅是"泄漏",它只是在过程停机时解除分配的一次性失败.

但是,如果你完全摆脱指针,那么你可以同时避免这两个问题,因为你的程序做的最后一件事就是破坏静态存储持续时间的对象:

#include <iostream>

class Singleton
{
public:
    ~Singleton()  { std::cout << "destruction!\n"; }

    static Singleton& getInstance() 
    {
        static Singleton instance;
        return instance;
    }

    void foo() { std::cout << "foo!\n"; }

private:
    Singleton() { std::cout << "construction!\n"; }
};

int main()
{
    Singleton::getInstance().foo();
}

// Output:
//   construction!
//   foo!
//   destruction!
Run Code Online (Sandbox Code Playgroud)

(现场演示)

甚至不需要指针!

这有一个额外的好处,即整个函数本质上是线程安全的,至少从C++ 11开始.