gpt4 book ai didi

c++ - 单例:是否存在内存泄漏?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:07:08 25 4
gpt4 key购买 nike

这是一个简单的单例:

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

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

if (!instance) {
instance = new Singleton();
};
return instance;
};
}

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

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

最佳答案

When main code calls Singleton::getInstance()->someMethod() for the first time, isn't the class instantiated twice?

没有。调用 Singleton 的静态成员不会实例化 Singleton,因此此处存在的唯一 Singleton 实例是您使用 创建的实例新的。而且你只创建它一次,因为一旦 instance 指向它,你就再也不会调用 new 了。

但是,您在这里遇到的一个问题是未能使 getInstance 成为静态成员函数。我认为这是一个打字错误/疏忽,否则,您的程序甚至无法编译。事实上,即使作为非静态成员,声明也是格式错误的。此外,构造函数应该是 private 以强制执行只有 getInstance 可以实例化类型的概念。

Will be there memory leak?

是的,这就是 Leak Detector 报告的内容。然而,它是最小的:问题是在你的程序关闭之前没有什么可以删除那个单例实例。

坦率地说,我不会为此担心。这可能是可以接受泄漏的罕见情况之一,主要是因为不仅仅是“泄漏”,它只是在进程关闭时取消分配的一次性失败。

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

#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!

( live demo )

甚至不需要指针!

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

关于c++ - 单例:是否存在内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30602861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com