#ifndef SINGLETON_H #define SINGLETON_H #include /** * 使用方法: * 1. 定义类为单例 (类声明时使用宏 SINGLETON): * class HelloWorld { * SINGLETON(HelloWorld) * public: * * 2. 在 cpp 文件中实现类的默认构造函数和析构函数 (已经在宏 SINGLETON 里被声明为 private 的了,所以必须实现) * * 3. 调用单例的函数: HelloWorld::instance()->method() * * 注意: * 1. 单例的创建不是线程安全的 * 2. 如果单例的类需要释放的资源和 Qt 底层的信号系统有关系,例如 QSettings 的数据没有保存,QSqlDatabase 的连接没有关闭等, * 需要在 main 函数返回前手动释放,否则有可能在程序退出时报系统底层的信号错误,因为 main 函数返回后 qApp 已经被回收, * 而资源的释放在 main 返回后,又和信号槽有关,所以就可能报错。 * 推荐实现方式: 可以在单例类的构造函数中给 qApp 的 aboutToQuit 信号绑定一个槽函数,在里面处理善后工作、释放资源等。 */ template class Singleton { public: static T* get_instance() { if (s_instance.isNull()) { s_instance.reset(new T()); // 此指针会在全局变量作用域结束时自动 deleted (main 函数返回后) } return s_instance.data(); } static void destroy_instance() { s_instance.reset(nullptr); } Singleton(const Singleton& other) = delete; Singleton& operator=(const Singleton& other) = delete; private: static QScopedPointer s_instance; }; template QScopedPointer Singleton::s_instance; /*-----------------------------------------------------------------------------| | Singleton Macro | |----------------------------------------------------------------------------*/ #define SINGLETON(Class) \ private: \ Class(); \ ~Class(); \ Class(const Class &other) = delete; \ Class& operator=(const Class &other) = delete; \ friend class Singleton; \ friend struct QScopedPointerDeleter; \ \ public: \ static Class* instance() { \ return Singleton::get_instance(); \ } \ \ static void destroy_instance() { \ Singleton::destroy_instance(); \ } #endif // SINGLETON_H