#pragma init_seg使特定的全局变量优先于其他的全局变量先构造
来源:互联网 发布:陈一发 整容 知乎 编辑:程序博客网 时间:2024/05/22 18:22
原文地址:http://blog.csdn.net/yuucyf/article/details/7062543
我们知道在C++中的全局变量的构造总是优先于Main之前(应该说程序的执行体),那对于同一个文件,不同文件中定义的全局变量的构造函数是怎么执行的呢?
1)对于同一个文件来说:
全局变量的构造顺序按照全局变量的声明来构造。
如:
- C_C g_C;
- C_A g_A;
- C_B g_B;
构造函数的执行顺序为:C_C(), C_A(), C_B(), 不管是在什么编译器上都是按照这样的顺序执行的.
2)对于不同文件来说:
全局变量的构造顺序是不确定的。
也就是说,在C.cpp文件中声明全局变量C_C g_objC, 在B.cpp文件中声明全局变量C_B g_objB, 在A.cpp文件中声明全局变量C_A g_objA, 那么这几个全局变量的构造函数的执行顺序是不确定的,也就是说它们构造函数执行的顺序是任意的,我们不能假设它们其中的一个是一定在另一个之前构造的。因为在C++标准中,处于同一编译单元(cpp)的全局对象按其声明次序初始化并倒序析构,但标准中没有说处于不同编译单元的全局对象的初始化顺序。
然而,当我们有这样的需求的时候我们怎么做到呢?如:假如有个Log对象负责程序日志的记录,如果程序结束时,有某个全局对象出现类似于资源释放失败的错误,该对象会调用Log记录错误,这时,Log可能已经被销毁了…… 这就是所谓的dead-reference问题。
这里就要引入我们在这篇文章着重介绍的部分.
3) 如何保证一个全局变量的构造函数的调用优先于所有的其他构造函数,而不管这些变量是否在同一个文件中.
利用预编译指令:#pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
- <strong>pragma init_seg(compiler)
- #pragma init_seg(lib)
- #pragma init_seg(user)
- #pragma init_seg("user_defined_segment_name")
- </strong>
init_seg 预处理器指令: 编译器、 库、 用户,和 user_defined_segment_name, 前三个指令的初始化优先次序依次降低,但都先于普通的全局变量构造,如cout就是使用compiler级别构造的。
注:一个源文件只能出现一次init_seg 指令.
pragma init_seg(compiler)是保留给微软C/C++ 运行库使用的,我们不应该使用它!
在我们自己的代码里,如果希望一些对象先于其他对象初始化,我们可以使用 #pragma init_seg(lib) 指令.
现在我们来实现一下决定全局变量的构造顺序:
(一) 对于同一个文件来说,我们把全局变量的构造函数的执行顺序强制更改.
如:
- //main.cpp
- C_C g_C;
- C_A g_A;
- C_B g_B;
对以上的代码,不管在什么环境下执行,构造函数执行顺序都是固定的,即先执行C_C(), 接着是C_A(), 最后是C_B(), 那么如果我们想更该为先执行C_A(), C_B(), 最后才执行C_C(),那我们这样更改:
- //A.pp
- C_A::C_A()
- {
- printf("C_A Constructor.\n");
- }
- //B.pp
- C_B::C_B()
- {
- printf("C_B Constructor.\n");
- }
- //C.pp
- C_C::C_C()
- {
- printf("C_C Constructor.\n");
- }
- C_C g_C;
- #pragma init_seg(lib)
- C_A g_A;
- C_B g_B;
- int main(int argc, char* argv[])
- {
- printf("Hello World!\n");
- return 0;
- }
执行结果如:
- C_A Constructor.
- C_B Constructor.
- C_C Constructor.
- Hello World!
(二)对于不同文件来说,我们把全局变量的构造函数的执行顺序强制更改.
如:以下代码文件:
- //A.pp
- C_A g_objA;
- C_A::C_A()
- {
- printf("C_A Constructor.\n");
- }
- //B.pp
- C_B g_objB;
- C_B::C_B()
- {
- printf("C_B Constructor.\n");
- }
- //C.pp
- C_C g_objC;
- C_C::C_C()
- {
- printf("C_C Constructor.\n");
- }
如果由于某种需求,我要先构造C_C,接着C_B和C_A任意一个,那我们如何做到?当然我们还是要依靠Init_Seg预编译指令.
代码如下:
- //A.pp
- C_A g_objA;
- C_A::C_A()
- {
- printf("C_A Constructor.\n");
- }
- //B.pp
- C_B g_objB;
- C_B::C_B()
- {
- printf("C_B Constructor.\n");
- }
- //C.pp
- #pragma init_seg(lib)
- C_C g_objC;
- C_C::C_C()
- {
- printf("C_C Constructor.\n");
- }
- //main.cpp
- #include "A.h"
- #include "B.h"
- #include "C.h"
- int main(int argc, char* argv[])
- {
- printf("Hello World!\n");
- return 0;
- }
执行结果如下:
- C_C Constructor.
- C_B Constructor.
- C_A Constructor.
- Hello World!
- #pragma init_seg使特定的全局变量优先于其他的全局变量先构造
- #pragma init_seg使特定的全局变量优先于其他的全局变量先构造
- 使用# pragma init_seg控制静态对象的构造
- 如何调用其他文件里面的全局变量
- C++全局变量构造函数的调用
- jQuery的内部全局变量和构造函数
- 零基础学python-16.5 模块间全局变量的修改以及其他访问全局变量的方法
- wince下全局变量的共享于不共享
- 主函数调用其他源文件定义的全局变量偶尔出错
- python global语句和其他访问全局变量的方法
- C++的全局变量,静态全局变量,常全局变量定义与声明
- 全局变量的赋值以及类的默认构造函数问题
- static全局变量与普通的全局变量区别
- 全局变量和静态全局变量的区别
- 静态全局变量和全局变量的区别
- static全局变量与普通全局变量的区别
- 全局变量和静态全局变量的区别
- c++ 静态全局变量 和 全局变量的区别
- uva6469禁位排序
- POJ1995 Raising Modulo Numbers 快速幂
- Linux进程间的通信-基于无序文件
- 华为-将无符号的指定bite位置1
- 截取txt文件中的第1623行到第1648行之间的文字
- #pragma init_seg使特定的全局变量优先于其他的全局变量先构造
- asp.net 退出登陆(解决退出后点击浏览器后退问题仍然可回到页面问题)
- 有了Docker,一分钟就可以在你的笔记本上快速部署Spark集群
- Windows 运行机制
- poj1067
- hud 4740 The Donkey of Gui Zhou(深搜DFS)
- JMS的例子
- hdu 1257 最少拦截系统
- Solaris下如何修改文件创建时间及查询