How to Call a Constructor from Another Constructor (Do Constructor Chaining) in C++

Can I call a constructor from another constructor (do constructor chaining) in C++?

C++11: Yes!

C++11 and onwards has this same feature (called delegating constructors).

The syntax is slightly different from C#:

class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};

C++03: No

Unfortunately, there's no way to do this in C++03, but there are two ways of simulating this:

  1. You can combine two (or more) constructors via default parameters:

    class Foo {
    public:
    Foo(char x, int y=0); // combines two constructors (char) and (char, int)
    // ...
    };
  2. Use an init method to share common code:

    class Foo {
    public:
    Foo(char x);
    Foo(char x, int y);
    // ...
    private:
    void init(char x, int y);
    };

    Foo::Foo(char x)
    {
    init(x, int(x) + 7);
    // ...
    }

    Foo::Foo(char x, int y)
    {
    init(x, y);
    // ...
    }

    void Foo::init(char x, int y)
    {
    // ...
    }

See the C++FAQ entry for reference.

Can constructor call another constructor in c++?

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.

Call constructor with different argument types from another constructor in C++17

Yes, you can define one constructor in terms of another. No, I don't think you can do it without some additional function.

A constructor which invokes another constructor of the same class is called a "delegating constructor", and uses the same sort of syntax as a member initializer list, but using the class's own name instead of its base classes and members:

ClassName::ClassName(SomeParam1 p1, SomeParam2 p2)
: ClassName(arg_expr1, arg_expr2, arg_expr3)
{ /* any other logic after the target constructor finishes */ }

But this case is a bit tricky because of the need for the intermediate object date_as_struct. Or with the updated question, just the need to do some parsing before entering another constructor. I'd solve this one by making an additional private constructor which takes the Date_as_struct:

class Date {
public:
explicit Date(int day = 1, int month = 1, int year = 0);
explicit Date(const string &date_as_string);
/* ... */
private:
struct Date_as_struct {
int day;
int month;
int year;
};

explicit Date(const Date_as_struct&);

static Date_as_struct ParseStringContainingDate(const std::string&);
};

Date_as_struct and ParseStringContainingDate are declared here as private, since it sounds like nothing else will really use them.

Then for the string constructor, you just have

Date::Date(const std::string& date_as_string)
: Date(ParseStringContainingDate(date_as_string))
{}

The Date(const Date_as_struct&) constructor can very easily delegate to Date(int, int, int) or vice versa, whichever is more natural for the actual member initialization.

Call one constructor from another

Like this:

public Sample(string str) : this(int.Parse(str)) { }

Constructor chaining in C++

The paragraph basically says this:

class X
{
void Init(params) {/*common initing code here*/ }
X(params1) { Init(someParams); /*custom code*/ }
X(params2) { Init(someOtherParams); /*custom code*/ }
};

You cannot call a constructor from a member function either. It may seem to you that you've done it, but that's an illusion:

class X
{
public:
X(int i):i(i){}
void f()
{
X(3); //this just creates a temprorary - doesn't call the ctor on this instance
}
int i;
};

int main()
{
using std::cout;
X x(4);
cout << x.i << "\n"; //prints 4
x.f();
cout << x.i << "\n"; //prints 4 again
}

Calling another constructor C++

Simply call a delegating constructor. Use a helper function to construct the vector<item>.

namespace {
vector<item> helper(char*buff, size_t num)
{
/* your implementation for re-packaging the data here */
}
}

Foo::Foo(char*buff, size_t num)
: Foo(helper(buff,num))
{}

Call constructor inside a call to another constructor

The problem is that B b(A(i)); is a function declaration and not a declaration for a variable named b of type B.

This is due to what is called most vexing parse. In particular, the statement:

B b(A(i)); //this is a declaration for a function named `b` that takes parameter of type A and has no return type 

the above is a declaration for a function named b that takes one parameter of type A and with return type of B.

To solve this, you can either use curly braces {} or double () to solve this:

Method 1

Use {} around A(i).

//----v----v------->declares a variable of type B and is not a function declaration
B b{A(i)};

Method 2

Use double parenthesis (()).

//-v--------v------>declares a variable of type B and is not a function declaration
B b( (A(i)) );


Related Topics



Leave a reply



Submit