C++的全局类和静态类的构造函数是在main函数之前调用的。但是,不同的类的构造函数以什么顺序调用呢?
对于g++编译器来说,这个顺序是由链接时,文件顺序决定的。
我们用一个例子来说明这一点。
我们有3个文件:t1.h, t1.cpp和tt1.cpp,内容分别是
t.h
#ifndef T_H
#define T_H
#include <stdio.h>
class A {
public:
A();
};
class B {
public:
B(){ a_ = NULL; }
void setA(A* a) { a_ = a; }
A * a() { return a_; }
static B _b;
private:
A *a_;
};
extern A *g_a;
#endif
tt.cpp
#include "t.h"
B B::_b;
A *g_a = NULL;
A::A()
{
B::_b.setA(this);
g_a = this;
}
t.cpp
#include "t.h"
A a;
int main()
{
printf("a=%p, b.a=%p, g_a=%p\n", &a, B::_b.a(), g_a);
}
t.h定义了类A和B,其中,在A的构造中,A将自己的指针付给B::_b.a_和g_a。
那么,如果以这样的顺序编译
g++ -o t tt.cpp t.cpp执行 ./t,得到的结果是

C++全局和静态类对象的构造函数在main函数前按链接文件顺序调用。以g++为例,构造函数顺序取决于源文件链接顺序。在给定的例子中,由于t.cpp先被链接,A的构造函数先执行,设置B::b_的成员a_,而B::B()随后执行,此时a_已被初始化为NULL,导致输出结果b.a=(nil)。这种不确定性可通过使用指针变量如g_a来避免,因为它在内存映射时已有确定值。
最低0.47元/天 解锁文章
519

被折叠的 条评论
为什么被折叠?



