全局构造函数按什么顺序调用

发布于 2024-12-01 14:00:53 字数 1281 浏览 1 评论 0原文

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

很好!正如我想要的那样。纯属运气?我的意思是池的 dtor 可以在销毁消费者 a 或 b 之前被调用,对吧?

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

In what order get the constructors of global object in C++ called?

This question arises in the context of a memory pool that manages the memory needs for some consumers. I was presented with a rather large source code which defines at global namespace some consumers just using heap functions. A memory pool should be added without changing the namespace of the consumers. So, I added a pool class and a definition at global namespace and modified each consumer class to get memory from the instance of the class "thePool". Unfortunately at the end of the execution when it comes to call all global destructors I get a nice segfault. gdb backtrace shows that the branch to pool::free produces the segfault. This sounds odd to me. However, I boiled it down to a very simple pool/consumer example which lives on the global namespace. Unfortunately this does not reproduce the segfault -- the destructor of pool gets called after all destructors of the consumer. Is this pure luck, or a well-educated guess of g++ 4.5 ?

Here the boiled down example:

#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() {
}

The output is:

pool::pool
consumer::consumer
pool::get
consumer::consumer
pool::get
consumer::~consumer
pool::free
consumer::~consumer
pool::free
pool::~pool

Nice! Just as I wanted it. Pure luck? I mean the dtor of pool could have been called before destroying consumer a or b, right?

The question to answer is: "In what order are the cons of global objects called?"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

以往的大感动 2024-12-08 14:00:53

全局变量按照声明的顺序进行初始化。因此它们的构造函数将按照它们初始化的顺序被调用。在一个翻译单元内确实如此。然而,语言规范并未定义跨多个翻译单元的初始化顺序。

它们的析构函数按照与通常初始化相反的顺序被调用。

Global variables are initialized in the order in which they're declared. So their constructor will be called in the same order in which they're initialized. This is true within one translation unit. However, the initialization order across multiple translation-units is not defined by the language specification.

And their destructors are called in the reverse order of their initialization as usual.

野の 2024-12-08 14:00:53

翻译单元之间未定义 - 但按其他声明的顺序。

Undefined between translation units- but in order of declaration else.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文