最简单的写法:

1
2
3
4
5
static MyClass* MyClass::Instance()
{
static MyClass inst;
return &inst;
}

过去很长一段时间一直都这么写,简单粗暴有效。但是直接声明静态对象会使编译出的可执行文件增大,也有可能出现其他的一些问题,所以利用了Qt自带的智能指针QScopedPointer和线程锁QMutex,改成了需要时才动态初始化的模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
static MyClass* MyClass::Instance()
{
static QMutex mutex;
static QScopedPointer<MyClass> inst;
if (Q_UNLIKELY(!inst)) {
mutex.lock();
if (!inst) {
inst.reset(new MyClass);
}
mutex.unlock();
}
return inst.data();
}

既保证了线程安全又防止了内存泄漏,效率也没降低太多,简直完美。

可惜每次都要重复这么几行实在麻烦,于是写了一个模板类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <class T>
class Singleton
{
public:
static T* Instance()
{
static QMutex mutex;
static QScopedPointer<T> inst;
if (Q_UNLIKELY(!inst)) {
mutex.lock();
if (!inst) {
inst.reset(new T);
}
mutex.unlock();
}
return inst.data();
}
};

使用的时候直接这样——

1
MyClass* inst = Singleton<MyClass>::Instance();

除了用模板类,还可以利用c++中强大的宏:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define DECLARE_SINGLETON(Class) \
Q_DISABLE_COPY(Class) \
public: \
static Class* Instance() \
{ \
static QMutex mutex; \
static QScopedPointer<Class> inst; \
if (Q_UNLIKELY(!inst)) { \
mutex.lock(); \
if (!inst) inst.reset(new Class); \
mutex.unlock(); \
} \
return inst.data(); \
}

然后声明的时候,填加一行这个宏:

1
2
3
4
5
class MyClass
{
DECLARE_SINGLETON(MyClass); // 声明单例模式
//...
}

好评好评。

当然,为了要保证真的是单例模式,还要把构造函数限制为private,不然以后什么时候忘记了这码事,在外面又new了一下就不好了。

另外Qt本身自带了一个宏Q_GLOBAL_STATIC,也有类似单例模式的效果,QThreadPool::globalInstance()函数的实现就是利用了这个宏。不过它的主要用处是声明全局变量,和Singleton还是有差别的。

https://blog.yeatse.com/2015/03/03/qt-singleton-implementation/

最新文章

  1. 蒙特卡洛树搜索算法(UCT): 一个程序猿进化的故事
  2. mysql SQL_CALC_FOUND_ROWS
  3. Visual Studio中的快捷键
  4. Android开发之多级下拉列表菜单实现(仿美团,淘宝等)
  5. 【转】Android 属性动画(Property Animation) 完全解析 (上)
  6. Android小项目之二 代码的组织结构
  7. zedboard启动过程分析
  8. lintcode:Length of Last Word 最后一个单词的长度
  9. HDU 1576 A/B 扩展欧几里德算法
  10. linux下启动和关闭网卡命令及DHCP上网
  11. 表格(table) 插件:支持当前行增行、删除。使用事件委托
  12. 大数据系列修炼-Scala课程05
  13. WebIM(2)---消息缓存
  14. python模块之PIL模块
  15. ExtJS:Grid数据导出至excel实例
  16. 洛谷P1072 Hankson 的趣味题(题解)
  17. HDU - 6314 Matrix(广义容斥原理)
  18. PHP微信模板消息发送
  19. Hue添加MySQL数据库
  20. BZOJ1805[Ioi2007]Sail船帆——线段树+贪心

热门文章

  1. jquery优化01
  2. HDU1561 The more, The Better(树形DP)
  3. HDU3037 Saving Beans(Lucas定理+乘法逆元)
  4. DataTable排序的一般方法
  5. HDU 2896 (AC自动机模板题)
  6. 响应式HTML5+CSS3 网站开发测试实践
  7. 关于inf的问题
  8. 【BZOJ】1076: [SCOI2008]奖励关(状压dp+数学期望)
  9. [LintCode] Implement Trie 实现字典树
  10. [转载]CAsyncSocket及CSocket注解