C++中关于全局对象的初始化顺序
2016-06-15 15:35
447 查看
在stackoverflow上看到下面这样一个问题:
这个问题很简单,意思就是两个全局不同类的instance,其中一个依赖另一个,怎么确保他们的构造顺序。也就是说O2依赖于o1,o2被实例化之前,我们要确保o1一定要被构造出来,或者说初始化。就上面来看,如果这样两个全局变量o1和o2在同一个编译单元,说白了就是在同一个cpp文件里,那么编译器会保证按照他们出现的顺序初始化。但是如果这样两个全局变量在不同的编译单元呢,这时候情况比较复杂了,编译器已经不能控制他们的构造顺序了,我们需要自己想办法确定他们的构造顺序,因为编译器不能定义不同编译单元全局变量的初始化顺序。下面是我的sample code, 这两个全局变量分别在不同的编译单元,请看代码:
在o1之前被构造出来的,这个应该是编译器随机选择的,我们不能确定o2和o1他们两个之间的构造顺序。
下面是一些办法,确定o1在o2之前一定被构造出来,因为在很多实际应用中,一些全局对象依赖于另一些全局对象的,虽然我们尽可能要少用全局变量,不过今天讨论的问题跟这个无关。请看修改过的代码:
很明显,o2依赖于o1, 而o1也在o2之前被构造出来了。
总结:
1.我们要尽可能少用全局变量
2.可以将一个对象的构造函数作为另一个对象构造函数的参数来保证他们的构造顺序
这个问题很简单,意思就是两个全局不同类的instance,其中一个依赖另一个,怎么确保他们的构造顺序。也就是说O2依赖于o1,o2被实例化之前,我们要确保o1一定要被构造出来,或者说初始化。就上面来看,如果这样两个全局变量o1和o2在同一个编译单元,说白了就是在同一个cpp文件里,那么编译器会保证按照他们出现的顺序初始化。但是如果这样两个全局变量在不同的编译单元呢,这时候情况比较复杂了,编译器已经不能控制他们的构造顺序了,我们需要自己想办法确定他们的构造顺序,因为编译器不能定义不同编译单元全局变量的初始化顺序。下面是我的sample code, 这两个全局变量分别在不同的编译单元,请看代码:
//************Independent.h************************* #ifndef INDEPENDENT_H #define INDEPENDENT_H class Independent { public: Independent(); virtual ~Independent(); protected: private: }; #endif // INDEPENDENT_Hpp******************************* #include "Independent.h" #include <iostream> using namespace std; Independent::Independent() { cout<<"Independent::Independent()."<<endl; } Independent::~Independent() { cout<<"Independent::~Independent()."<<endl; } Independent o1; //*********************Dependent.h***************************** #ifndef DEPENDENT_H #define DEPENDENT_H #include "Independent.h" class Dependent { public: virtual ~Dependent(); Dependent(); protected: private: }; #endif // DEPENDENT_H //***********************Dependent.cpp***************************************** #include "Dependent.h" #include <iostream> #include "Independent.h" using namespace std; Dependent::Dependent() { cout<<"Dependent::Dependent()."<<endl; } Dependent::~Dependent() { cout<<"Dependent::~Dependent()."<<endl; } Dependent o2; //***********************************main.cpp********************************* int main() { return 0; }
在o1之前被构造出来的,这个应该是编译器随机选择的,我们不能确定o2和o1他们两个之间的构造顺序。
下面是一些办法,确定o1在o2之前一定被构造出来,因为在很多实际应用中,一些全局对象依赖于另一些全局对象的,虽然我们尽可能要少用全局变量,不过今天讨论的问题跟这个无关。请看修改过的代码:
//*************Independent.h******************** #ifndef INDEPENDENT_H #define INDEPENDENT_H class Independent { public: Independent(); virtual ~Independent(); protected: private: }; #endif // INDEPENDENT_H
//*************Independent.cpp******************** #include "Independent.h" #include <iostream> using namespace std; Independent::Independent() { cout<<"Independent::Independent(), o1"<<endl; } Independent::~Independent() { cout<<"Independent::~Independent()."<<endl; } const Independent *o1;
//*************dependent.h******************** #ifndef DEPENDENT_H #define DEPENDENT_H #include "Independent.h" class Dependent { public: virtual ~Dependent(); Dependent(Independent* a); protected: private: Dependent(); }; #endif // DEPENDENT_H
//*************Dependent.cpp******************** #include "Dependent.h" #include <iostream> #include "Independent.h" using namespace std; extern Independent *o1; Dependent::Dependent() { cout<<"Dependent::Dependent(), o2"<<endl; } Dependent::Dependent(Independent* a) { if(a == NULL) a = new Independent(); cout<<"Dependent::Dependent(Independent* a) o2"<<endl; } Dependent::~Dependent() { co a350 ut<<"Dependent::~Dependent()."<<endl; } Dependent o2(o1);
//*************main.cpp******************** #include <iostream> using namespace std; int main() { return 0; }
很明显,o2依赖于o1, 而o1也在o2之前被构造出来了。
总结:
1.我们要尽可能少用全局变量
2.可以将一个对象的构造函数作为另一个对象构造函数的参数来保证他们的构造顺序
相关文章推荐
- memset
- C++程序设计语言练习7.9 迭代器的使用
- C—文件操作
- C++中引用(&)的用法和应用实例
- C语言反转单链表
- HDOJ 2011 多项式求和
- C++primer函数引用形参 左值和右值d额
- C++实践参考——人数不定的工资类
- VC中遍历文件夹下的文档及子文件夹
- C++ 的explicit 关键字
- c语言中冒泡排序、插入排序、选择排序算法比较
- [leetcode] 【字符串】 12. Integer to Roman
- C语言程序报告
- c++ STL学习之stack堆栈总结
- C++实践题:我的数组类
- C++程序设计语言练习7.8 二维数组操作
- C++—文件操作
- C语言打印当前时间
- loki 练习
- C语言宏定义##连接符和#符的使用