c++ - 静态字段的析构函数。单例实现

标签 c++ design-patterns static singleton

所以,经典的简单单例实现如下:

class Singleton
{
private:
    static Singleton* singleton;
    Singleton() {}
public:
    static Singleton* getInstance();        
};

cpp 文件:

Singleton* Singleton::singleton = 0;

Singleton* Singleton::getInstance()
{
    if (!singleton)
    {
        singleton = new Singleton;
    }

    return singleton;
}

我在这里看到内存泄漏 - '因为 new 没有 delete。但是在 C++ 中没有静态析构函数,所以我们不关心这个内存泄漏?

最佳答案

内存泄漏不仅仅是没有匹配空闲的分配。当您拥有可以回收的内存时,因为该对象不再使用,但实际上并没有被释放。事实上,许多内存泄漏是程序中有代码释放内存的情况,但无论出于何种原因,它都没有被调用(例如,引用循环)。有很多关于如何检测这些泄漏的研究。 this paper 是此类工具的一个很好的例子。

在单例的情况下,我们没有泄漏,因为该单例存在于整个程序中。它的生命周期永远不会结束,因此没有被回收的内存不是问题。

也就是说,您上面的代码并不是大多数人会实现单例的方式。规范的 C++ 实现是这样的:

class Singleton
{
private:
    /* No instantiation. */
    Singleton() {}

    /* Explicitly disallow copying. */ 
    Singleton(const Singleton&) = delete;
    Singleton& operator= (const Singleton&) = delete;

    /* In C++03, the above would be written as
     *
     *    Singleton(const Singleton&);
     *    Singleton& operator= (const Singleton&);
     * 
     * and you'd just leave the methods unimplemented.
     */
public:
    static Singleton& getInstance();        
};

.cpp 文件:

Singleton& Singleton::getInstance() {
    /* Have a static local variable representing the unique instance.  Since
     * it's static, there is only one instance of this variable.  It's also only
     * initialized when getInstance is called.
     */
    static Singleton theInstance;
    return theInstance;
}

现在根本没有动态分配 - 内存由编译器分配,并且可能驻留在代码或数据段中,而不是在堆中。另请注意,您必须明确禁止复制,否则您可能会得到许多单例的克隆。

这样做的另一个优点是 C++ 保证在程序退出时(假设程序正常终止),theInstance 的析构函数确实会在程序结束时触发。因此,您可以使用所需的所有清理代码定义析构函数。

希望这会有所帮助!

关于c++ - 静态字段的析构函数。单例实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9968162/

相关文章:

c++ - 从 C++ (Qt5) 向 QML 项发送信号

java - 了解生成线程的类上的线程和同步

java - 通知护士患者必须服用药物的频率

amazon-web-services - aws cli 日志过滤模式排除

ios - 我如何继承 AVPlayer?

C++ 在类中声明一个静态对象

java - 静态方法中的android上下文未定义

c++ - 'function1' 和 'function2' 之间的歧义 (C++)

c++ - Qt QFont 选择等宽字体不起作用

c++ - 无限级数的并行计算