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

发布于 2024-11-15 10:06:21 字数 460 浏览 1 评论 0原文

#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 技术交流群。

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

发布评论

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

评论(6

时光与爱终年不遇 2024-11-22 10:06:21

您没有调用构造函数。您只是创建一个临时的 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.

是伱的 2024-11-22 10:06:21

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


该代码片段

if(b_ == 10) {
  A();
}

创建并销毁 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

if(b_ == 10) {
  A();
}

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 one T constructor call on that object. And vice versa, if you call a T constructor (which is another valid view of the above code) then, in C++98, you're creating a T 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 the A 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. :-)

落花随流水 2024-11-22 10:06:21

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.

心在旅行 2024-11-22 10:06:21

A(); 创建 A 的新(临时)实例,调用其默认构造函数。

您不能从构造函数调用另一个构造函数。


如果您有很多初始化工作要做,您可以创建一个私有方法并在两个构造函数中调用它。

A(); creates a new (temporary) instance of A, 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.

镜花水月 2024-11-22 10:06:21

在这段代码中:

if(b_ == 10) {
  A();
}

您将一个临时 A() 放在堆栈上,而不是调用 A 的默认构造函数。

为了执行您的意图,您需要将默认构造函数中的代码分解为辅助函数,然后从这里调用该函数和默认构造函数。

In this code:

if(b_ == 10) {
  A();
}

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.

离旧人 2024-11-22 10:06:21

使用 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++?

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