focus on linux, c/c++, lua

静态变量的初始化问题

首先感谢孔雀的热心回复,我首先承认看到这个问题后我思考了不到3分钟就放弃了,也没有认真去google(手里的事情太多)。我就没抱希望的没完没了的给孔雀留言,寻思作者回复了是人家人品好,没回复也是情理之中,毕竟大家都读过how to ask,但孔雀给了我一个很大的意外,再次感谢。
原文地址:
http://www.cppblog.com/kongque/archive/2010/02/28/108635.html
贴上我的一段测试代码:

#include "stdafx.h"
template 
<typename T>
struct Singleton
{
     
struct object_creator
    
{
            object_creator()
            

                printf(
"object_creator\n");
                Singleton
<T>::instance(); 
            }

            inline 
void do_nothing()const {}
    }
;
     
static object_creator create_object;
    
public:
    typedef T object_type;
    
static object_type& instance()
    
{
            printf(
"instance\n");
            
static object_type obj;
            create_object.do_nothing();
            
return obj;
    }

       
}
;

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


int _tmain(int argc, _TCHAR* argv[])
{    
    
int sint = Singleton<int>::instance();
    getchar();
    
return 0;
}
打印结果
object_creator
instance
instance
本文我较生僻的是:Boost源码,template的技巧,所以我只给出我对静态函数和静态变量的初始化的一些看法,错误的地方请指教!
首先
template <typename T>
typename Singleton<T>::object_creator
Singleton<T>::create_object;
这个初始化的语法就把我弄懵了,我拆开看了下
template <typename T> typename
Singleton<T>::object_creator   // 这行是变量的类型
Singleton<T>::create_object;   // 这行是变量的定义
文中的重点是在多线程的程序中如何确保每个线程得到的obj是自己想要的。明确的两个概念是:
1,类的成员静态变量在进入main之前已被初始化
2,函数内部的局部静态变量在该函数第一次被调用时初始化,只初始化一次
所以该代码首先执行的初始化create_object,调用其默认的无参构造函数,在构造函数中调用了instance,这个时候obj也被初始化了,所以在main中再显式的调用instance时就直接得到了一个已经初始化了的obj了。
这样做究竟是怎么达到线程安全的呢?
简单来讲就是不管是线程A,还是线程B调用instance,它们所调用的obj都是已经初始化好的obj,以前旧的做法
class Foo
{
 
public:
     
static Foo& getSingleton()
      
{
          
static Foo foo;
          
return foo;
      }

  
 
private:
     Foo();
 }
;
如果A线程先调用了getSingleton(),那么B再调用的时候,得到的是按照A的想法初始化过的foo了(尽管没什么差别,因为没有参数),那么这个foo也许就不是B想要的了。

posted on 2010-03-06 10:59 zuhd 阅读(5026) 评论(6)  编辑 收藏 引用 所属分类: c/c++

评论

# re: 静态变量的初始化问题 2010-03-06 11:38 孔雀

彼此彼此,相得益彰吧。  回复  更多评论   

# re: 静态变量的初始化问题 2010-03-06 15:22 David Fang

确实,在多线程的时候脑袋是需要多根弦  回复  更多评论   

# re: 静态变量的初始化问题 2010-03-06 23:09 Benjamin

首先类是个数据类型,其次,在类的静态方法里只能使用类的静态成员变量。
另外类的静态变量初始化的顺序是定义的顺序。
用时 ,我们只要能保证它能正确的初始化就可以。在多线程中应用也遵循这样的原则  回复  更多评论   

# re: 静态变量的初始化问题 2010-03-07 12:48 小苏

1,类的成员静态变量在进入main之前已被初始化

我觉得这个结论应该是不正确的吧?
不信你把main第一行代码注释了看,打印结果.

int _tmain(int argc, _TCHAR* argv[])
{
//int sint = Singleton<int>::instance();
getchar();
return 0;
}  回复  更多评论   

# re: 静态变量的初始化问题 2010-03-07 18:02 zuhd

@小苏
class CTest1
{
public:
CTest1()
{
printf("init\n");
}
};

class CTest2
{
public:
static CTest1 m_test;
};

CTest1 CTest2::m_test;

这段代码按道理讲是和上面的代码功能类似的,
这段是可以打印出来的。
至于上面那段为什么没有打印,
思考中(难道模板必须要实例化才能成为有效代码??),期待高手解答  回复  更多评论   

# re: 静态变量的初始化问题 2011-06-13 16:44 liang

@zuhd
确实是这样子的
我正在找解决方案
不想要这个特性  回复  更多评论   


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