以什么顺序获取C ++中全局对象的构造函数?
这个问题出现在内存池的上下文中,该内存池管理一些消费者的内存需求。我看到了一个相当大的源代码,它在全局命名空间中定义了一些消费者只使用堆函数。应添加内存池而不更改使用者的名称空间。因此,我在全局命名空间中添加了一个池类和一个定义,并修改了每个使用者类以从类“thePool”的实例中获取内存。不幸的是,在执行结束时,当调用所有全局析构函数时,我得到了一个很好的段错误。 gdb backtrace显示分支到pool :: free会产生段错误。这听起来很奇怪。但是,我把它归结为一个非常简单的池/消费者示例,它位于全局命名空间中。不幸的是,这并没有重现段错误 - 池的析构函数在消费者的所有析构函数之后被调用。这是纯粹的运气,还是对g ++ 4.5的一个受过良好教育的猜测?
这里有一个简单的例子:
#include<iostream>
using namespace std;
struct pool {
pool() {
cout << "pool::pool" << endl;
}
~pool() {
cout << "pool::~pool" << endl;
}
void get() {
cout << "pool::get" << endl;
}
void free() {
cout << "pool::free" << endl;
}
};
pool thePool;
struct consumer {
~consumer() {
cout << "consumer::~consumer" << endl;
thePool.free();
}
consumer() {
cout << "consumer::consumer" << endl;
thePool.get();
}
};
consumer a,b;
int main() {
}
输出结果为:
pool::pool
consumer::consumer
pool::get
consumer::consumer
pool::get
consumer::~consumer
pool::free
consumer::~consumer
pool::free
pool::~pool
尼斯!就像我想要的那样。纯粹的运气?我的意思是在破坏消费者a或b之前可以调用游泳池的dtor,对吧?
要回答的问题是:“全局对象的缺点是以什么顺序调用?”
答案 0 :(得分:8)
全局变量按声明的顺序初始化。因此,它们的构造函数将按照它们初始化的相同顺序调用。这在translation unit内是正确的。但是,语言规范未定义跨多个转换单元的初始化顺序。
他们的析构函数按照与初始化相反的顺序调用。
答案 1 :(得分:4)
翻译单位之间未定义 - 但按照声明的顺序排列。