现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

浅谈C++变量初始化顺序

2012-09-01 06:57 工业·编程 ⁄ 共 1585字 ⁄ 字号 暂无评论

    为了相对透彻的了解C程序运行期的初始化顺序,首先介绍一些名词定义。用过Java的同志都知道, Java是一种跨平台语言。真的是所有的平台都能自如的运行Java程序吗?当然不可能。运行它的前提是你需要安装Java Run-time(JRE)。C语言也需要自己的运行期类库,windows系统正好支持这种类库,所以C++程序可以顺利的在windows系统上运行了。这个类库叫C Run-time(CRT), CRT这个名词可能并不陌生,大家在很多地方都看见过它。它建立了C程序运行环境。

  • 有些同志可能想过这样的问题。C程序怎么找到main函数的呢?其实是CRT执行了你的main函数或者WinMain函数的。我们在VC IDE的选项中可以填入Entry-point symbol,如wWinMainCRTStartup。这就是给CRT定义了一个入口宏,根据这个宏CRT会运行相应类型的Main函数。由于这里我们讨论初始化顺序,所以main的具体调用过程不做介绍了。 现在我们整理一下C程序的启动过程。在你开始执行一个C程序的时候, CRT库会根据不同的入口宏调用相应的CRT初始化函数,在这个函数中会做一些CRT运行一系列准备工作,按次序为:获得win32版本、对堆进行初始化、初始化操作系统接口、获得命令行参数、初始化stdio接口等等操作。
  • .
  • . . 之后的部分就是我们关心的东西了,CRT会根据函数指针表对我们定义的静态变量进行初始化
  • .static void _CALLTYPE4 _initterm (

    • PFV * pfbegin,
    • PFV * pfend
    • )

    .#else /* _M_MPPC */ .void _CALLTYPE4 _initterm (

    • PFV * pfbegin,
    • PFV * pfend
    • )

    .#endif /* _M_MPPC */ .{

    • /*
    • * walk the table of function pointers from the top down, until
    • * bottom is encountered. Do not skip the first entry.
    • */
    • for ( ;pfbegin < pfend ; pfbegin++)

    • {
      • /*
      • * if current table entry is non-NULL (and not -1), call
      • * thru it from end of table to begin.
    • */
    • if ( *pfbegin != NULL && *pfbegin != (PFV) -1 )

    • (**pfbegin)();
    • }

    .}

        静态变量进行初始化顺序是基类的静态变量先初始化,然后是它的派生类。直到所有的静态变量都被初始化。这里需要注意全局变量和静态变量的初始化是不分次序的。这也不难理解,其实静态变量和全局变量都被放在公共内存区。可以把静态变量理解为带有“作用域”的全局变量。在一切初始化工作结束后,main函数会被调用,如果某个类的构造函数被执行,那么首先基类的成员变量会被初始化。
        要请注意的是,成员变量的初始化次序只与定义成员变量的顺序有关,与构造函数中初始化列表的顺序无关。因为成员变量的初始化次序是根据变量在内存中次序有关,而内存中的排列顺序早在编译期就根据变量的定义次序决定了。这点在EffectiveC++中有详细介绍。

    • bbb的成员变量定义:
    • private:
      • int n1;
      • int n2;
    • bbb的构造函数:
    • bbb::bbb()
    • :n2(1),
    • n1(2)
    • {
    • }
    • 汇编代码:
    • 00401535 mov eax,dword ptr [ebp-4]
    • 00401538 mov dword ptr [eax+4],2
    • 0040153F mov ecx,dword ptr [ebp-4]
    • 00401542 mov dword ptr [ecx+8],1
    • 然后依照派生链初始化派生类的成员函数。
    • .
    • . 那么变量的初始化顺序就应该是:
      • 1基类的静态变量或全局变量
      • 2派生类的静态变量或全局变量
      • 3基类的成员变量
      • 4派生类的成员变量

     

    给我留言

    留言无头像?