我有这样的单例结构:
// 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()方法。I have such singleton structure:
// 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; }And here is the usage of this singleton:
Root::Get(); // Some code calling related to mManager1 and mManager2 Root::Get().Deinitialize();The questions are:
This is memory safely to use such singleton structure? How can I automate deletion of mInstance (call dtor manually). Because the user could forget to call Deinitialize() method.最满意答案
对于退出main()后不访问单例的单线程应用程序,您可以使用一种相当简单的方法来自动执行所有操作:
Root& Root::get() { static std::unique_ptr<Root> rc(new Root()); return *rc; }此上下文中的static意味着变量在第一次调用函数时初始化,然后保持put。 C ++运行时安排static变量rc在某个时刻被销毁。 对于在进入main()之前启动线程的多线程应用程序,您需要一种不同的方法,以确保静态变量仅由线程初始化。
也就是说,请注意我强烈建议不要使用反模式Singleton (也称为全局数据 )。 上面的代码示例不构成任何形式的推荐! 您想要使用单件的几个有效用途,大多数用途不是。 我见过的所有有效用途都使用了不可变的Singleton。 可变单例对象倾向于成为同步点,并倾向于像全局数据那样模糊使用数据。
For a single-threaded application where the singleton isn't accessed after exiting main() you can use a fairly simple approach which does everything automatically:
Root& Root::get() { static std::unique_ptr<Root> rc(new Root()); return *rc; }The static in this context means that the variable is initialized the first time the function is called and then stays put. The C++ run-time arranges for the static variable rc to be destroyed at some point. For multi-threaded appplications where threads are started before entering main() you need a different approach which makes sure that the static variable is initialized only by on thread.
That said, please note that I strongly recommend not to employ the anti-pattern Singleton (also known as Global Data). The above code sample doesn't constitute a recommendation of any sort! There are few valid uses where you want to use a singleton, most uses are not. All valid uses I have seen use an immutable Singleton. Mutable singleton objects tend to become a synchronization point and tend to obfuscate the use data as global data does.
更多推荐
发布评论