COMPASSi/trunk/code/inc/Util/include/Singleton.h

72 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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