孔雀开发小屋

专注并致力于手机客户端开发
<2011年11月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

统计

  • 随笔 - 103
  • 文章 - 0
  • 评论 - 251
  • 引用 - 0

常用链接

留言簿(38)

随笔分类

随笔档案

关注的博客

朋友的博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜

boost库的Singleton的实现
在工作中遇到不少情况使用singleton模式,下面采用的是最简单的一种形式:
 1 class Foo
 2 {
 3 public:
 4     static Foo& getSingleton()
 5     {
 6         static Foo foo;
 7         return foo;
 8     }
 9 
10 private:
11     Foo();
12 };
这种实现,在单线程情况下,简单而有效。

对于线程安全的singleton的实现,网上有不少讨论。这两天看到boost库中的一种实现,没有使用锁机制,而是充分利用了C++的语言特性较好的解决了多线程情况下使用singleton的问题。
boost的singleton的实现基于以下假设:良好的设计在进入main函数之前应该是单线程的。
我们可以使用全局变量的方式来设计singleton,并且保证在使用该singleton之前其已经被正确的初始化,如何做到?且看代码:
 1 template <typename T>
 2 struct Singleton
 3 {
 4     struct object_creator
 5     {
 6         object_creator(){ Singleton<T>::instance(); }
 7         inline void do_nothing()const {}
 8     };
 9 
10     static object_creator create_object;
11 
12 public:
13     typedef T object_type;
14     static object_type& instance()
15     {
16         static object_type obj;
17         create_object.do_nothing();
18         return obj;
19     }
20     
21 };
漂亮而巧妙的实现。
但是上面的实现还是有一点小的缺憾,那就是只能调用类的默认构造函数,不能调用带参数的构造函数。

附:
非常抱歉,上面这个代码是有点问题的。感谢各位童鞋及时回复并指出问题所在。现在补上缺失的初始化部分。
1 template <typename T>
2 typename Singleton<T>::object_creator
3 Singleton<T>::create_object;


posted on 2010-02-28 22:48 孔雀 阅读(6205) 评论(21)  编辑 收藏 引用 所属分类: C/C++

评论

# re: boost库的Singleton的实现 2010-03-01 11:09 毛毛

对于带参数构造函数的支持,可以参考Loki的实现
http://www.cppprog.com/2009/0905/156.html
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-01 13:14 kongque

@毛毛
谢谢,很好的文章!loki的做法确实解决boost的这点不足。
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-01 13:50 99网上书城

是大叔大叔的
  回复  更多评论    

# re: boost库的Singleton的实现[未登录] 2010-03-01 14:01 zuhd

没怎么看懂上面一段代码,作者能详细的解释下吗?谢谢
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-01 14:17 coder

obj\Debug\main.o||In function `_ZN1AC1Ev':|
::instance()]+0x25)||undefined reference to `Singleton<A>::create_object'|
||=== Build finished: 1 errors, 0 warnings ===|

编译没通过,提示这个错误,IDE codeblock
  回复  更多评论    

# re: boost库的Singleton的实现[未登录] 2010-03-01 15:02 zuhd

初始化的顺序是怎样的?感觉像是在循环调用
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-01 16:07 coder

@coder
template<typename T>
typename Singleton<T>::object_creator Singleton<T>::create_object ;

要加一句这个初始化 create_object .
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-01 19:05 kongque

@coder
感谢coder童鞋的提醒,确实需要一个初始化操作。
  回复  更多评论    

# re: boost库的Singleton的实现[未登录] 2010-03-02 23:37 zuhd

我看不懂这个单件的实现,哪位高手能解释下,谢谢!
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-03 10:36 kongque

@zuhd
你可能是觉得object_creater的构造函数和instance()这两个函数之间存在相互调用关系,不能确定到底谁先执行,谁后执行。
我给你一个建议就是,你可以将代码自己运行一下,在object_creator的构造函数和instance函数中的开始和结束部分都是用cout或printf打印一句话,通过这个执行过程,你就可以看出来这个执行的顺序了。
希望对你有所帮助。
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-03 10:57 99书城官方网站

时的减肥时间的
  回复  更多评论    

# re: boost库的Singleton的实现[未登录] 2010-03-04 10:34 zuhd

没明白你加的那段代码放在什么地方,麻烦你贴个完整的代码好吗?谢谢
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-05 09:27 kongque

@zuhd
1 template <typename T>
2 struct Singleton
3 {
4 struct object_creator
5 {
6 object_creator(){ Singleton<T>::instance(); }
7 inline void do_nothing()const {}
8 };
9
10 static object_creator create_object;
11
12 public:
13 typedef T object_type;
14 static object_type& instance()
15 {
16 static object_type obj;
17 create_object.do_nothing();
18 return obj;
19 }
20
21 };
22
23 template <typename T>
24 typename Singleton<T>::object_creator
25 Singleton<T>::create_object;
26
27 int main()
28 {
29 return 0;
30 }
  回复  更多评论    

# re: boost库的Singleton的实现[未登录] 2010-03-05 10:04 zuhd

谢谢孔雀的热心回复,我还是有很多问题不懂:
1,template <typename T>
typename Singleton<T>::object_creator
Singleton<T>::create_object;
这句话的初始化把我弄糊涂了,我甚至连这句话的语法都没有看懂
2,我下了断点
如果我写了int sint = Singleton<int>::instance();
这样instance就会断进去两次,请解释下!谢谢
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-05 20:46 kongque

@zuhd
1. template <typename T>
typename Singleton<T>::object_creator
Singleton<T>::create_object;
这句的意思就是类的静态成员的初始化。只不过是模板类需要使用typename进行类型说明而已。只是语法上有点生涩,但是事实上就是类的静态数据成员的初始化而已。

2. instance断进去两次是对的。第一次是object_create的构造函数中调用,这个过程在main之前就已经完成了。第二次是你调用。
不知道我的解释是否清楚。
你可以在main()进入之后,在int sint = Singleton<int>::instance(); 之前打印一句话,可以印证这个过程。
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-06 10:16 zuhd

谢谢,懂了,很少用到模板,有时间要充电一下
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-07 18:53 Rolf

更小白的问题,去掉 create_object.do_nothing();
这句调用后,为什么在Main前就不执行object_creator(){ Singleton<T>::instance(); }了?
  回复  更多评论    

# re: boost库的Singleton的实现 2010-03-08 18:55 coder

@Rolf
这个问题不是很小白。。。如果Singleton不是模板的话没有do_nothing也会执行,但是如果在模板中就不执行了,可能和模板的实例化有关。
  回复  更多评论    

# re: boost库的Singleton的实现 2010-04-10 11:27 欲三更

说到底boost是用事先构造单例对象的方法规避使用锁。
看来不使用锁和“使用时构造”这两个便利只能取一个,具体实现时要分析利弊了。
  回复  更多评论    

# re: boost库的Singleton的实现 2010-04-28 16:11 ajohn

boost的这个东西不要去用,details的东西都是不确定的,下个版本需要改进的
  回复  更多评论    

# re: boost库的Singleton的实现 2012-09-13 20:10 sding

时间有点长了,但是还是想问下:
为什么在main函数里面实例化时是非线程安全的?
  回复  更多评论    

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理