(简单 C++ 概念)构造函数/析构函数调用的意外输出
给定以下代码:
#include <iostream>
using namespace std;
class Foo {
public:
Foo () { c = 'a'; cout << "Foo()" << endl; }
Foo (char ch) { c = ch; cout << "Foo(char)" << endl; }
~Foo () { cout << "~Foo()" << endl; }
private:
char c;
};
class Bar : public Foo {
public:
Bar () { cout << "Bar()" << endl; }
Bar (char ch) : Foo(ch) { cout << "Bar(char)" << endl; }
~Bar () { cout << "~Bar()" << endl; }
};
Foo f1; static Bar b1;
int main()
{
Bar b2;
{
static Foo f2('c');
Foo f3;
Bar b3 ('d');
}
return 0;
}
(您可以直接将其粘贴到编译器中)
我预期的示例输出的第一部分是正确的:
Foo()
Foo()
Bar()
Foo()
Bar()
Foo(char)
Foo()
Foo(char)
Bar(char)
~Bar()
~Foo
~Foo()
~Bar()
~Foo()
~Foo()
但是我得到了两个静态的析构函数输出对象 static Bar b1;
和 static Foo f2('c');
错误。
最后一部分的正确答案是:
~Bar()
~Foo()
~Foo()
我得到:
~Foo()
~Bar()
~Foo()
这是我的推理:
我明白所有本地对象都会在静态对象之前被破坏。剩下的两个静态对象中 static Bar b1;
和 static Foo f2('c');
,static Foo f2('c');
> 出现在最后,因此它首先被析构,因为析构函数是按照其创建的相反顺序被调用的。
但 static Foo f2('c');
并没有首先被破坏,static Bar b1;
才被破坏。为什么?
Given this code:
#include <iostream>
using namespace std;
class Foo {
public:
Foo () { c = 'a'; cout << "Foo()" << endl; }
Foo (char ch) { c = ch; cout << "Foo(char)" << endl; }
~Foo () { cout << "~Foo()" << endl; }
private:
char c;
};
class Bar : public Foo {
public:
Bar () { cout << "Bar()" << endl; }
Bar (char ch) : Foo(ch) { cout << "Bar(char)" << endl; }
~Bar () { cout << "~Bar()" << endl; }
};
Foo f1; static Bar b1;
int main()
{
Bar b2;
{
static Foo f2('c');
Foo f3;
Bar b3 ('d');
}
return 0;
}
(You can just paste this directly into a compiler)
The first part of my expected sample output is correct:
Foo()
Foo()
Bar()
Foo()
Bar()
Foo(char)
Foo()
Foo(char)
Bar(char)
~Bar()
~Foo
~Foo()
~Bar()
~Foo()
~Foo()
But I get the destructor output of the two static objects static Bar b1;
and static Foo f2('c');
wrong.
The correct answer for the last part is:
~Bar()
~Foo()
~Foo()
I get:
~Foo()
~Bar()
~Foo()
This is my reasoning:
I understand that all local objects are destructed before static objects. Of the two remaining static objects static Bar b1;
and static Foo f2('c');
, static Foo f2('c');
appears last, so it is destructed first, because destructors are called in the reverse order of their creation.
But static Foo f2('c');
isn't destructed first, static Bar b1;
is. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
修改你的程序:
在 g++ 4.5.2 中生成以下输出:
你看到最后一个被破坏的是非静态全局变量
Foo f1
。编辑:
正如其他人提到的,如果变量来自不同的翻译单元,则具有静态存储持续时间的变量的初始化顺序是不确定的,但当它们位于同一翻译单元中时可以定义它们。
通过构造函数调用进行的初始化(如本示例中所示)称为动态初始化,并且
局部静态变量的初始化指定为
并且由于具有静态存储持续时间的变量的销毁应该按照其构造的相反顺序,因此类型为
Foo
和Bar 在这个例子中实际上已经定义了。
再次强调,当你有多个翻译时,你最好不要依赖初始化的顺序。
Modified you program :
Which generates the following output in g++ 4.5.2:
You see that the last destructed one is the non-static global variable
Foo f1
.EDIT:
As the others mentioned, the initialization order of variables with static storage duration is unspecific if the variables are from different translation units, but they can be defined when they are in the same translation unit.
Initialization by constructor calls (as in this examples) are called
dynamic initialization
, andThe initialization of local static variables is specified as
And as the destruction of variables with static storage duration should be in the reverse order of their construction, so the order of construction and destruction of the variables with types
Foo
andBar
in this example is in fact defined.Again, when you have multiple translation, you'd better not to rely on the order of initialization.
请参阅此 C++ FAQ 条目,静态的初始化顺序对象未定义。 不要依赖它。
See this C++ FAQ entry, the initialization order for static objects is undefined. Don't rely on it.