72 lines
2.8 KiB
C
72 lines
2.8 KiB
C
|
#ifndef SINGLETON_H
|
|||
|
#define SINGLETON_H
|
|||
|
|
|||
|
#include <QScopedPointer>
|
|||
|
|
|||
|
/**
|
|||
|
* 使用方法:
|
|||
|
* 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 <typename T>
|
|||
|
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<T>& operator=(const Singleton& other) = delete;
|
|||
|
|
|||
|
private:
|
|||
|
static QScopedPointer<T> s_instance;
|
|||
|
};
|
|||
|
|
|||
|
template <typename T> QScopedPointer<T> Singleton<T>::s_instance;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*-----------------------------------------------------------------------------|
|
|||
|
| Singleton Macro |
|
|||
|
|----------------------------------------------------------------------------*/
|
|||
|
#define SINGLETON(Class) \
|
|||
|
private: \
|
|||
|
Class(); \
|
|||
|
~Class(); \
|
|||
|
Class(const Class &other) = delete; \
|
|||
|
Class& operator=(const Class &other) = delete; \
|
|||
|
friend class Singleton<Class>; \
|
|||
|
friend struct QScopedPointerDeleter<Class>; \
|
|||
|
\
|
|||
|
public: \
|
|||
|
static Class* instance() { \
|
|||
|
return Singleton<Class>::get_instance(); \
|
|||
|
} \
|
|||
|
\
|
|||
|
static void destroy_instance() { \
|
|||
|
Singleton<Class>::destroy_instance(); \
|
|||
|
}
|
|||
|
|
|||
|
#endif // SINGLETON_H
|