43
class A{
  A(int a = 5){
    DoSomething();
    A();
  }
  A(){...}
}

Can the first constructor call the second one?

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
MainID
  • 29,070
  • 19
  • 57
  • 70
  • 1
    Similar question here: https://http://stackoverflow.com/questions/308276/c-call-constructor-from-constructor – Jon Cage Jan 09 '15 at 15:24

6 Answers6

68

Not before C++11.

Extract the common functionality into a separate function instead. I usually name this function construct().

The "so-called" second call would compile, but has a different meaning in C++: it would construct a new object, a temporary, which will then be instantly deleted at the end of the statement. So, no.

A destructor, however, can be called without a problem.

Pavel Radzivilovsky
  • 18,794
  • 5
  • 57
  • 67
  • 5
    +1 - and you should add that it will be possible to call constructors from constructors in the same class in the next C++ version (C++0x). See http://www2.research.att.com/~bs/C++0xFAQ.html#delegating-ctor – Klaim Dec 13 '09 at 23:53
  • Can you give an example of the construct() function? I know it's quite simple but I think people would find it useful. – MattCochrane Apr 08 '17 at 23:36
  • Yeah the real issue is initializing references as if you have a bunch you have to duplicate all the initializations in every constructor overload and can't factor them out to a common constructor subroutine. AND they can only be initialized in the pre-{ initializers. – peterk Nov 10 '17 at 15:06
19

Not before C++0x, no.

BUT, just out of academic interest I've come up with a really horrible way* to do it using a placement operator "new" (someone care to point out how portable this is?)

#include <new>
#include <iostream>

class A
{
public:
    A(int i, int j)
        : i_(i), j_(j) { }

    A(int i)
    { new (this) A(i, 13); }

    int i_,j_;
};

int
main() {
    A a1(10,11), a2(10);
    std::cout
        << a1.i_ << ", "
        << a1.j_ << std::endl
        << a2.i_ << ", "
        << a2.j_ << std::endl;
    return 0;
}

*Hell no, I don't write this in the production code.

Alex B
  • 82,554
  • 44
  • 203
  • 280
  • 1
    I think it's pretty portable; placement-new is in the ISO C++ standard. "Other uses, however, include calling a constructor directly, something which the C++ language does not otherwise permit." From wikipedia: http://en.wikipedia.org/wiki/Placement_syntax – emvee Jun 24 '10 at 13:20
  • 4
    What happens if A derives from a class B ? B's constructor will be called, and then A, which will then call new A' (another A constructor), and overwrite everything already done by B, and then call B again, then A'. Conclusion: if B does something meaningful (i.e. allocating a resource), this will break code (i.e. provoke a resource leak). – paercebal Oct 16 '10 at 08:19
  • @paercebal yes, this also won't work if A is an abstract class. – Alex B Oct 16 '10 at 10:03
6

The answer is in fact "yes", but as others have suggested, it doesn't do what you want. You can of course use the constructor of a base class, either implicitly or explicitly:

struct B {
    B() {}
    B( int x ) {}
};

struct A : public B {
    A() {}    // calls B() implicitly
    A( int a, int b ) : B( b ) {} // calls B(int) explicitly
};
3

This is an old question; however,

class A{
  A(int a = 5){
    DoSomething();
    A();
  }
  A(){...}
}

could be

class A{
  A(int a = 5){
    *this = A();
    DoSomething();
  }
  A(){...}
}
supaflav
  • 99
  • 4
  • 1
    I think the assignment `*this = A();` it would use the default copy constructor (if you haven't defined one) which may not be what you want? – austinmarton Apr 20 '16 at 22:43
3

Not directly. There are a few ways to work around this.

From the initializer list of your class' constructor, you can call a constructor on any base class, and on all member variables.

So you can usually refactor your class and split it into several smaller ones to solve the problem. The commonly executed code can be placed in a member object or perhaps a base class. Then each of the main class' constructors just have to decide which construcotr to use to initialize that member.

class B {
  B() {  }
  B(int b) { DoSomething(); }
}
class A{
  A(int a = 5) : b(a) { } // call B's constructor which does something
  A() : b() {} // call B's constructor which does nothing

  B b;
};
jalf
  • 243,077
  • 51
  • 345
  • 550
2

As pointed out by Pavel Radzivilovsky in his answer, since C++ 11, it is possible. It is the same syntax as for explicitely calling the parent's class constructor from a child class. This is useful when a class needs to have multiple constructors (say, a default constructor and a constructor with attribute initialization) but some operations have to be done in all cases. This allows to avoid code repetitions.

Here is an example:

class A
{
public:

    A()
    {
         foo();
    }

    A(Attribute attribute) : A()
    {
         this->attribute = attribute;
    }

    //------ some other code --------

private:

    Attribute attribute;
    void foo()
    {...}

    //------ some other code -------
};

In this simple example, I assume that the function foo() needs to be called in all cases for the object to be correctly initialized. With this syntax, if the second constructor (with attribute initialization) is called, it will first perform the operations in the default constructor before executing the instructions in the attribute-initialization constructor.

It can also be done the other way around: the default constructor can call another constructor with default parameters.

Before C++ 11, it was necessary to duplicate the common instructions of all constructors or define methods that do the actual object initialization.

Pierre Wargnier
  • 397
  • 3
  • 10