static 变量初始化顺序的问题和解决方案

http://www.cppblog.com/yindf/archive/2009/03/20/77304.aspx


最近在coding的时候,写了这么一段代码:

 A.h

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

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

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

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

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


这是因为先在 B::B()使用了静态变量x, 而x还没有初始化。

如果多个cpp文件里包含多个static 变量,初始化的顺序不可以预知。


如果在.h中定义static 就表明这个变量只是属于include这个头文件的编译单元。


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

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

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

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

看看下面的代码:

 1 class  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}
;

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


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

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

如果和boost::function合作起来,效果更佳。look!
 1 class  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
12 void  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就到这里吧。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值