1
#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?

Bertrand Marron
  • 21,501
  • 8
  • 58
  • 94
marcot
  • 321
  • 2
  • 8
  • 1
    Which compiler are you using, with which statements? Constructors are not allowed to call other constructors in C++03. (The draft standard C++0x allows it though) – Billy ONeal Jun 15 '11 at 23:11

6 Answers6

6

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.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • -1 "You aren't calling the constructor". He is, by way of creating a temporary. Also, "You can't call other constructors [on this object] from a constructor [body]" is just balderdash. You can, via placement new, but it's decidedly not a good idea. In short, your answer sounds good, but it's not technically correct in any respect. – Cheers and hth. - Alf Jun 15 '11 at 23:22
  • @Alf P. Steinbach: Though technically correct; your input serves no purpose other than to confuse. The answer here is perfectly good(valid) for any beginner. – Martin York Jun 16 '11 at 00:26
  • @Martin: this answer needlessly confuses things, makes the simple complex, and is incorrect. you say you think that is "perfectly good". i do not believe that you believe what you're saying. – Cheers and hth. - Alf Jun 16 '11 at 00:46
  • @Alf: Don't be pedantic. OK, yes he is calling the constructor, but it is not called as a member function of the current object, which was obviously his intention. – Peter Alexander Jun 16 '11 at 06:56
5

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

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
2

A(); doesn't do what you think it does. (e.g. call the default constructor)

It creates a temporary object, which then is discarded.

Jason S
  • 184,598
  • 164
  • 608
  • 970
1

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.

Bertrand Marron
  • 21,501
  • 8
  • 58
  • 94
1

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.

Colen
  • 13,428
  • 21
  • 78
  • 107
0

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

Community
  • 1
  • 1
SJuan76
  • 24,532
  • 6
  • 47
  • 87