http://blog.csdn.net/windboyzsj/article/details/2790485

最近接触的一个项目要用到单件模式,我像往常一样哒哒(敲击键盘ing)一个单件模式的典型结构很快就出现在我的面前:

  1. class Singleton
  2. {
  3. public:
  4. ~Singleton(){}
  5. static Singleton* Instance()
  6. {
  7. if (_instance == NULL)
  8. {
  9. _instance = new Singleton();
  10. }
  11. return _instance;
  12. }
  13. private:
  14. Singleton(){}
  15. static Singleton* _instance;
  16. };
  17. Singleton* Singleton::_instance = NULL;

不知道为什么,这次突然觉得new这个单词太耀眼了,熟悉c++的程序员都知道,有new就离不开delete,既然单件模式共用一个实例,那么这个实例什么时候释放呢。带着好奇我在它的析构函数加了个打印语句,但由于new操作是在堆里分配内存,估计它的析构函数不会被调用,而试验结果确实如此。这样一来那单件模式的析构函数不是完全废了吗,如果这个单件类还有指针成员用new分配了空间那又应该在哪里释放?单件的实例又应该如何释放。当然,我们可以在程序退出时通过 delete Singleton::Instance(); 来释放内存并触发析构函数。但这样一来,写好的类给别人用时就要叮嘱别人,用完后一定要释放- - !,再说别人不一定记得...有没有一种机制让单件模式自动释放?百度,google很久,发现关注这个问题的寥寥无几,但还是给我找到了一篇文章让我再次领略C++的灵活。按此文章大概把代码修改如下;

  1. class Singleton
  2. {
  3. public:
  4. ~Singleton(){}
  5. static Singleton* Instance()
  6. {
  7. if (_instance == NULL)
  8. {
  9. _instance = new Singleton();
  10. }
  11. return _instance;
  12. }
  13. private:
  14. Singleton(){}
  15. static Singleton* _instance;
  16. class Cleaner
  17. {
  18. public:
  19. Cleaner(){}
  20. ~Cleaner()
  21. {
  22. if(Singleton::Instance())
  23. delete Singleton::Instance();
  24. }
  25. };
  26. static Cleaner clr;
  27. };
  28. Singleton* Singleton::_instance = NULL;

事先声明我用VC6.0编译上面的代码(当然我有加一些测试代码)发现,clr并没有实例化,当然也就是没有析构了,暂时不清楚为什么,但这里的设计却是很值得品味。它通过一个内嵌类和一个静态成员来实现了自动释放的机制,相当于为单件加了个垃圾回收器。整个设计最巧妙的地方在于static Cleaner clr;这个声明,由于是静态成员,系统会在栈里分配内存,回收工作也就由系统自动完成了。这个思路另我想起了通过静态变量来实现类的静态构造函数,他们都有异曲同工之处。至于私有的内嵌类主要是防止单件类的专用垃圾筒被打扰...

虽然上面代码没有达到目的,但根据他的思路,可以做一下调整,把Cleaner的实例化延迟,下面贴出整个测试代码,一下代码在VC6编译通过。

  1. #include <iostream.h>
  2. class Singleton
  3. {
  4. public:
  5. ~Singleton(){cout<<"singleton deconstruct"<<endl;}
  6. static Singleton* Instance()
  7. {
  8. if (_instance == NULL)
  9. {
  10. _instance = new Singleton();
  11. static Cleaner cl; //延迟到这里
  12. }
  13. return _instance;
  14. }
  15. void Print(char* str)
  16. {
  17. cout<<"singleton print:"<<str<<endl;
  18. }
  19. private:
  20. Singleton(){cout<<"singleton construct"<<endl;}
  21. static Singleton* _instance;
  22. class Cleaner
  23. {
  24. public:
  25. Cleaner(){cout<<"cleaner construct"<<endl;}
  26. ~Cleaner()
  27. {
  28. cout<<"cleaner deconstruct"<<endl;
  29. if(Singleton::Instance())
  30. delete Singleton::Instance();
  31. }
  32. };
  33. };
  34. Singleton* Singleton::_instance = NULL;
  35. int main(int argc, char* argv[])
  36. {
  37. Singleton::Instance()->Print("print 1");
  38. Singleton::Instance()->Print("print 2");
  39. return 0;
  40. }

最新文章

  1. Shell文本处理 - 分割合并与过滤
  2. Stream Player control
  3. Linux使用jstat命令查看jvm的GC情况
  4. 矩阵快速幂 ZOJ 3497 Mistwald
  5. 【Android开发学习笔记】【第三课】Activity和Intent
  6. 单击改变input的边框颜色
  7. 洛古 P1373 小a和uim之大逃离
  8. JAVA 函数式接口与c#委托对应关系(一)
  9. SolrCloud阶段总结
  10. jquery.placeholder.js的使用
  11. 解决中文乱码( jsp表单提交中文时出现乱码)
  12. redhat 安装GCC-4.8.3
  13. Ionic在windows下的环境配置难题
  14. pandas的读写
  15. users-and-groups-in-linux
  16. Spring中bean作用域属性scope
  17. ssh连接失败,提示 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
  18. casperjs,phantomjs,slimerjs and spooky
  19. (转)WebSocket的原理
  20. iOS- 非整星的评分控件(支持小数)

热门文章

  1. IDE警告信息不应该被忽略
  2. js截取字符串显示引号两种方法
  3. iOS富文本的使用
  4. [python] 线程锁
  5. IAP 破解漏洞验证
  6. 实现毛玻璃模糊效果/DRNRealTimeBlur
  7. Vrapper-Eclipse的vim插件安装方法
  8. 推荐一个C语言学习教程
  9. H3C dhcp 中继
  10. 6.9 Android 优缺点