全局构造函数的命令是什么顺序

时间:2011-08-28 17:50:15

标签: c++ constructor global

以什么顺序获取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,对吧?

要回答的问题是:“全局对象的缺点是以什么顺序调用?”

2 个答案:

答案 0 :(得分:8)

全局变量按声明的顺序初始化。因此,它们的构造函数将按照它们初始化的相同顺序调用。这在translation unit内是正确的。但是,语言规范未定义跨多个转换单元的初始化顺序。

他们的析构函数按照与初始化相反的顺序调用。

答案 1 :(得分:4)

翻译单位之间未定义 - 但按照声明的顺序排列。