gpt4 book ai didi

c++ - 单例实例释放

转载 作者:行者123 更新时间:2023-11-30 01:27:24 24 4
gpt4 key购买 nike

我有这样的单例结构:

// Hpp
class Root : public boost::noncopyable
{
public:
~Root();

static Root &Get();

void Initialize();
void Deinitialize();

private:
Root(); // Private for singleton purposes
static Root *mInstance;

Manager1 *mManager1;
Manager2 *mManager2;
};


// Cpp
Root *Root::mInstance = nullptr;

Root::Root()
{
mInstance = this;

// Managers are using `mInstance` in their constructors
mManager1 = new Manager1();
mManager2 = new Manager2();

mInstance->Initialize();
}

Root::~Root() { delete mManager1; delete mManager2; }

Root &Root::Get()
{
if (mInstance == nullptr) mInstance = new Root();
return *mInstance;
}

void Root::Deinitialize()
{
delete mInstance;
}

下面是这个单例的用法:

Root::Get();
// Some code calling related to mManager1 and mManager2
Root::Get().Deinitialize();

问题是:

  • 使用这种单例结构是否安全?
  • 如何自动删除 mInstance(手动调用 dtor)。因为用户可能会忘记调用 Deinitialize() 方法。

最佳答案

对于退出 main() 后无法访问单例的单线程应用程序,您可以使用一种相当简单的方法自动执行所有操作:

Root& Root::get() {
static std::unique_ptr<Root> rc(new Root());
return *rc;
}

此上下文中的 static 表示变量在第一次调用函数时初始化,然后保持不变。 C++ 运行时安排 static 变量 rc 在某个时刻被销毁。对于在进入 main() 之前启动线程的多线程应用程序,您需要一种不同的方法来确保静态变量仅由线程初始化。

也就是说,请注意我强烈建议不要使用-模式单例(也称为全局数据)。以上代码示例不构成任何形式的推荐!您想要使用单例的有效用途很少,大多数用途都不是。我见过的所有有效用途都使用不可变的单例。可变单例对象往往会成为一个同步点,并且会像全局数据一样混淆使用数据。

关于c++ - 单例实例释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8980855/

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