Constructors from C++11 allow us to do constructor chaining. For example, we are able to code this:

Class Foo
{
public:
    Foo()
    {
    }   

    Foo(int n): Foo()
    {
    }  
};

I have tried out delegating Foo() in both the member initialization list and in the body of the code. I receive the same return values in both situations. My question is if there are actually any differences in both methods? If they are the same, is there any advantage over applying one over the other?

1

There are 1 best solutions below

0
hlt On

[class.base.init]/6 is fairly clear in how to delegate constructors, and it cannot be done in the body of the constructor.

An example

#include <iostream>

struct A
{
    A() : a(42) {}
    A(int) : A() {}

    int a = 17;
};

struct B
{
    B() : b(42) {}
    B(int) { B(); }

    int b = 17;
};

int main()
{
    A a{0};
    B b{0};
    std::cout << a.a << " " << b.b << std::endl;
}

The idea is very simple: Each of the two structs exposes a constructor taking a single int (that is ignored). A delegates to its default constructor in the member initializer list (setting a to 42). B attempts to do the same in the body of the constructor.

This example compiles[godbolt], and calls the right constructors (A(int) and B(int)), but the outcome is very different:

$ ./a.out
42 17

B's default constructor was never called

Why this happens

What B(int) does is not actually delegating the constructor. Instead, it constructs a new, temporary object of type B (just like how you could do B b = B();), and immediately discards it. It is not delegating anything in any way.

The only way to delegate a constructor is to call it in the member initializer list. You can also only delegate to one constructor at a time.[This does not apply to constructors of base classes invoked in a very similar fashion]