[英]c++ variable/instance initializaiton order across different Translation units
Thanks in advance. 提前致谢。
I saw these codes in some real project. 我在某个实际项目中看到了这些代码。 I just simplified them to express my problem here. 我只是简化它们以在这里表达我的问题。 The base class puts the this pointer into the a vector(vec) in its constructor. 基类将this指针放入其构造函数中的vector(vec)中。 Using this trick, we can leverlage the dynamic bonding to call the derived classes' method outside(in main func). 使用此技巧,我们可以利用动态绑定在外部(在主函数中)调用派生类的方法。 The key point is to put the vector definition in Bash.h, and declaration in main.cpp. 关键是将向量定义放在Bash.h中,并将声明放在main.cpp中。
My quesiton is, the output is not what I want. 我的问题是,输出不是我想要的。 Why the vec is initialized and used in one Translation units( base.c , we can see the size is 1), then in other Translation units( main.c , we can see the size become 0), is intialized and cleared again? 为什么将vec初始化并在一个转换单元( base.c ,我们看到大小为1)中使用,然后在其他转换单元( main.c ,我们看到大小变为0)中被初始化并再次清除? I want to know the intialization order accoross different Translation units. 我想知道初始化顺序会赋予不同的翻译单位。 Seem that the Derive::dInstance is first, then vec is second, but why? 似乎Derive :: dInstance是第一个,然后vec是第二个,但是为什么呢?
Base.h Base.h
#ifndef BASE_H
#define BASE_h
#include<iostream>
#include<vector>
using namespace std;
class Base{
public:
Base();
virtual void speak();
};
#endif
Base.cpp Base.cpp
#include"Base.h"
vector<Base*> vec;
Base::Base() {
vec.push_back(this);
cout << "Base's constructor" << endl;
cout << "Base() vector size: " << vec.size() << endl;**
}
void Base::speak() {
cout << "I am Base" << endl;
}
Derive.h Derive.h
#ifndef DERIVE_H
#define DERIVE_h
#include<iostream>
#include"Base.h"
class Derive: public Base {
public:
Derive();
virtual void speak();
static Derive dInstance;
};
#endif
Derive.cpp Derive.cpp
#include "Derive.h"
// static member definition
Derive Derive::dInstance;
Derive::Derive() {
cout << "Derived's construtor" << endl;**
}
void Derive::speak() {
cout << "I am Derived" << endl;
}
main.cpp main.cpp中
#include<iostream>
#include"Base.h"
using namespace std;
extern vector<Base*> vec;
int main(int argc, char *argv[]) {
cout << "vector size: " << vec.size() << endl;
for(vector<Base*>::iterator iter = vec.begin(); iter != vec.begin(); iter++) {
(*iter)->speak();
}
}
Output: 输出:
Base's constructor Base() vector size: 1 Derived's constructor main() vector size: 0
It's the “ static
initialization order fiasco” . 这是“ static
初始化顺序惨败” 。
The order of initialization between translation units of static
(or global) variables is not defined. 未定义static
(或全局)变量的转换单元之间的初始化顺序。 So think about what happens if the Derived.cpp
file is initialized before Base.cpp
, then you add to a vector that isn't initialized (constructed) leading to undefined behavior , then the vector is initialized. 所以,想想,如果发生了什么Derived.cpp
前文件被初始化Base.cpp
,然后添加到导致不确定的行为未初始化向量(构建), 那么矢量被初始化。
At first,there is no rule for the intialization order accoross different Translation units. 起初,对于初始化顺序没有规定不同翻译单元的规则。
And, Global variable and global static variable will be initialized before main function. 并且,全局变量和全局静态变量将在主函数之前初始化。 Local static variable which is belong to function FuncA() will be initialized at the first time the FuncA() is called. 属于函数FuncA()的局部静态变量将在首次调用FuncA()时初始化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.