c – 静态字段的析构函数.单例实现

所以,经典的简单的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;
}

我在这里看到内存泄漏 – ‘cos没有删除新的.但是在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保证在程序退出(假设程序正常终止)时,该函数的析构函数将确实在程序结束时触发.因此,您可以使用所需的所有清理代码定义析构函数.

希望这可以帮助!

转载注明原文:c – 静态字段的析构函数.单例实现 - 代码日志