C++中的构造函数执行顺序

mar*_*cot 1 c++ constructor

#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;
}
Run Code Online (Sandbox Code Playgroud)

这打印:

Default
a=1
b=1
Run Code Online (Sandbox Code Playgroud)

也就是说,它在b_ == 10时进入默认构造函数,但在不是时则进入默认构造函数.但它不会更改aa中的值,即使它进入Default构造函数.

为什么?

Pet*_*der 6

你没有调用构造函数.你只是创建一个临时的,A然后立即销毁它.您不能从当前标准(C++ 03)中的构造函数调用其他构造函数,即使在C++ 0x中,也只能从初始化列表中调用其他构造函数.


Che*_*Alf 5

到目前为止,大多数答案都说您没有调用构造函数。您将看到构造函数调用的输出。因此,请忽略那些通过过度简化而否认现实的答案。


代码片段

if(b_ == 10) {
  A();
}
Run Code Online (Sandbox Code Playgroud)

创建和销毁类的临时对象A

作为创建的一部分,A调用默认构造函数来初始化对象。


C++98 规则旨在确保除非您使用非常低级的功能来强加相反的意愿,否则类型对象的每次创建都T对应T于对该对象的一次构造函数调用。反之亦然,如果您调用T构造函数(这是上述代码的另一个有效视图),那么在 C++98 中,您正在创建一个T对象。您可以调用 C++构造函数调用保证:创建 = 构造函数调用。

构造函数调用保证意味着构造函数调用失败是对象创建失败:如果构造函数失败,那么你就没有对象。

这使事情简化了很多。

例如,它说如果你这样做new A,并且A默认构造函数失败,那么你就没有对象。因此,分配给该对象的内存会自动释放。这样即使对象构造失败,表达式也不会泄漏内存——而不是对象,你只会得到一个异常。

这几乎是美丽的。:-)