posts - 18,  comments - 104,  trackbacks - 0
最近在coding的时候,写了这么一段代码:

 A.h
1// A.h
2#include <map>
3
4class A
5{
6public:
7    static std::map<intint> x;
8}
;

A.cpp
1// A.cpp
2#include "A.h"
3
4std::map<intint> Test::x;

很简单,也很正常,看看用法吧。

main.cpp
 1class B
 2{
 3public:
 4    B();
 5}
;
 6
 7class C
 8{
 9public:
10    static B b;
11}
;
12
13B C::b;
14
15B::B()
16{
17    A::x[1= 2;
18}

19
20void main()
21{
22    A::x[3= 3;
23}

好了,按照上面的写法,把代码分别放到3个文件里面,编译,通过, 链接,通过,运行,挂了!!why?
解决方案很简单,把A.cpp里面的那句定义放到main.cpp里面就好了。

问题在于两个static变量分别在两个不同的文件里,A.cpp 里面那static变量要在main.cpp前初始化才行,可是编译器不知道呀,结果main里面的先初始化了,等到调用A.cpp里面那个变量时,已经来不及啦。

这个就是依赖编译器初始化顺序的程序,如果有人运行没有挂,那恭喜啦,等到它挂的时候你可要哭了。

上面的解决方案太烂了,如果程序规模很大,就完了,比如有好几个cpp里面要用到A.cpp里面那个变量,放哪个里面好呢?
这时候,Scott Mayer的Singleton就是解决方案啦,它能保证静态变量在使用前被初始化。

看看下面的代码:
 1class static_
 2{
 3public:
 4   template <int N, class T>
 5   static T& var()
 6   {
 7       static T instance;
 8       return instance;
 9   }

10
11private:
12   ~static_() {}
13}
;

有了这个定义,想用静态变量的时候就爽啦~~,用的时候:
1static_::var<0, std::string>() = ":)"
2static_::var<0, std::map<intint> >()[0= 3;
3static_::var<1, std::string>() = "haha";


现在的效果就是,想让Test里面有什么,他就有什么,我指静态变量。注意啦,第一个模板参数是为了可以定义同种类型的多个变量,就相当于
var_0, var_1...

是不是感觉有点动态语言的特性了,变量不用定义就可以用。而且变量初始化顺序也不用关心啦,因为所有的变量会在使用前初始化完毕。

如果和boost::function合作起来,效果更佳。look!
 1class Fun
 2{
 3public:
 4    Fun()
 5        : UId(&static_::var<0, std::string>)
 6    {
 7    }

 8    // interface for static variable.
 9    boost::function<std::string& (void)> UId;
10}
;
11
12void main()
13{
14    Fun f1, f2;
15    // set static from f1
16    f1.UId() = "abc";
17    // get static from f2
18    std::string str = f2.UId();
19}

好了,static就到这里吧。
posted on 2009-03-20 14:16 尹东斐 阅读(4637) 评论(5)  编辑 收藏 引用

FeedBack:
# re: static 变量初始化顺序的问题和解决方案。
2009-03-20 14:31 | 陈梓瀚(vczh)
final solution:不要用不是singleton的全局变量,singleton不要循环依赖。  回复  更多评论
  
# re: static 变量初始化顺序的问题和解决方案。
2009-03-20 14:55 | 尹东斐
@陈梓瀚(vczh)

很精辟,赞。  回复  更多评论
  
# re: static 变量初始化顺序的问题和解决方案。
2009-03-22 17:28 | 阿福1
# re: static 变量初始化顺序的问题和解决方案。
2010-09-28 17:36 | 网络监控
如何控制static变量析构的顺序呢?  回复  更多评论
  
# re: static 变量初始化顺序的问题和解决方案。
2010-10-14 16:34 | 匿名
main.cpp 编译不过,没有include "A.h"
加入后可以正常运行  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(4)

随笔档案

文章分类

文章档案

相册

好友博客

搜索

  •  

最新评论

阅读排行榜

评论排行榜