开发者

Constructor execution order in C++

#include <cstdio>

struct A {
  int a;
  A() {
    a = 2;
    printf("Default\n");
  }
  A(int b_) {
    a = 1;
    if(b_ == 10) {
      A();
    }
  }
};

int main(i开发者_运维技巧nt 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?


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.


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. :-)


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(); 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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜