C++ 中的构造函数执行顺序
#include <cstdio>
struct A {
int a;
A() {
a = 2;
printf("Default\n");
}
A(int b_) {
a = 1;
if(b_ == 10) {
A();
}
}
};
int main(int argc, char **argv) {
A a(10);
printf("a=%d\n", a.a);
A b(11);
printf("b=%d\n", b.a);
return 0;
}
这将打印:
Default
a=1
b=1
也就是说,当 b_ == 10 时,它进入默认构造函数,但如果不是,则不会进入默认构造函数。但它不会更改 aa 中的值,即使它进入默认构造函数也是如此。
为什么?
#include <cstdio>
struct A {
int a;
A() {
a = 2;
printf("Default\n");
}
A(int b_) {
a = 1;
if(b_ == 10) {
A();
}
}
};
int main(int argc, char **argv) {
A a(10);
printf("a=%d\n", a.a);
A b(11);
printf("b=%d\n", b.a);
return 0;
}
This prints:
Default
a=1
b=1
That is, it enters the Default constructor when b_ == 10, but not when it's not. But it doesn't change the value in a.a, even though it enters the Default constructor.
Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您没有调用构造函数。您只是创建一个临时的
A
,然后立即销毁它。您不能从当前标准 (C++03) 中的构造函数调用其他构造函数,即使在 C++0x 中,您也只能从初始化列表中调用其他构造函数。You aren't calling the constructor. You're just creating a temporary
A
then destroying it immediately. You can't call other constructors from a constructor in the current standard (C++03), and even in C++0x, you can only call other constructors from the initialisation list.到目前为止,大多数答案都说您没有调用构造函数。您将看到构造函数调用的输出。因此,请忽略那些过于简单化而否认现实的答案。
该代码片段
创建并销毁
A
类的临时对象。作为创建的一部分,
A
默认构造函数被调用来初始化对象。C++98 规则旨在确保除非您使用非常低级的功能来强加您相反的意愿,否则
T
类型的对象的每次创建都恰好对应于一个T
对该对象的构造函数调用。反之亦然,如果您调用T
构造函数(这是上述代码的另一个有效视图),那么在 C++98 中,您将创建一个T
对象。你可以称C++构造函数调用保证:创建=构造函数调用。构造函数调用保证意味着构造函数调用失败就是对象创建失败:如果构造函数失败,那么您就没有对象。
这大大简化了事情。
例如,它表示如果您执行
new A
,并且A
默认构造函数失败,那么您就没有对象。因此,分配用于保存该对象的内存将自动释放。因此,即使对象构造失败,该表达式也不会泄漏内存——您只会得到一个异常,而不是一个对象。这几乎是美丽的。 :-)
Most answers so far say that you're not calling a constructor. You're seeing the output of the constructor call. So just disregard those answers that are denying reality by over-simplifying.
The code snippet
creates and destroys a temporary object of class
A
.As part of the creation the
A
default constructor is called to initialize the object.The C++98 rules are designed to ensure that unless you use very low level functionality to impose your contrary will, every creation of an object of type
T
corresponds to exactly oneT
constructor call on that object. And vice versa, if you call aT
constructor (which is another valid view of the above code) then, in C++98, you're creating aT
object. You can call that the C++ constructor call guarantee: creation = constructor call.The constructor call guarantee means, among other things, that a constructor call failure is an object creation failure: if a constructor fails, then you don't have an object.
Which simplifies things a lot.
For example, it says that if you do
new A
, and theA
default constructor fails, then you don't have an object. So the memory that was allocated to hold that object, is automatically deallocated. And so that expression does not leak memory even if the object construction fails -- instead of an object, you just get an exception.It's almost beautiful. :-)
A();
并没有像你想象的那样做。 (例如调用默认构造函数)它创建一个临时对象,然后将其丢弃。
A();
doesn't do what you think it does. (e.g. call the default constructor)It creates a temporary object, which then is discarded.
A();
创建A
的新(临时)实例,调用其默认构造函数。您不能从构造函数调用另一个构造函数。
如果您有很多初始化工作要做,您可以创建一个私有方法并在两个构造函数中调用它。
A();
creates a new (temporary) instance ofA
, calling its default constructor.You cannot call another constructor from a constructor.
If you have a lot of initializing to do, you could create a private method and call it in both constructors.
在这段代码中:
您将一个临时 A() 放在堆栈上,而不是调用 A 的默认构造函数。
为了执行您的意图,您需要将默认构造函数中的代码分解为辅助函数,然后从这里调用该函数和默认构造函数。
In this code:
You're putting a temporary A() on the stack, not calling the default constructor of A.
To do what you intend, you'll need to factor out the code in the default constructor into a helper function, then call that function from here and the default constructor.
使用 A()(在 A(int b) 中),您正在创建一个新的、不同的对象。
Googlr 是这样说的: 我可以在 C++ 中从另一个构造函数调用构造函数(进行构造函数链接)吗?
With A() (in A(int b)), you are creating a new, different object.
Googlr says this: Can I call a constructor from another constructor (do constructor chaining) in C++?