Initializing fields in constructor - initializer list vs constructor body

C++Parameters

C++ Problem Overview


I have been working in c++ for some time now, but I am unsure about the difference between

public : Thing(int _foo, int _bar): member1(_foo), member2(_bar){}

and

public : Thing(int _foo, int _bar){
    member1 = _foo;
    member2 = _bar;
}

I have a feeling that they do the same thing, but is there a practical difference between these 2 syntaxes. Is one of these safer then the other, and do they handle default parameters differently.

Not totally accustomed to the first example so if I made a mistake on it I apologize.

C++ Solutions


Solution 1 - C++

They are not the same if member1 and member2 are non-POD (i.e. non-Plain Old Data) types:

public : Thing(int _foo, int _bar){
    member1 = _foo;
    member2 = _bar;
}

is equivalent to

public : Thing(int _foo, int _bar) : member1(), member2(){
    member1 = _foo;
    member2 = _bar;
}

because they will be initialized before the constructor body starts executing, so basically twice the work is done. That also means, if the type of these members don't have default constructor, then your code will not compile.

Solution 2 - C++

The first one is the recommended best practice, as it is more idiomatic and avoids re-initializing fields for types which do have a default constructor (i.e. non-primitive types).

When you only initialize a member inside the constructor body, the compiler generates a default member initialization statement for you if it can, so you end up doubly initializing it. This may not be a big deal in some cases, but may be serious performance overhead if constructing the object is expensive.

Update

However, user defined types without a(n explicitly defined or generated) default constructor can't be initialized this way, so a compiler error is produced. The same is true for const and reference fields - these can only be initialized explicitly in the member initializer list.

Solution 3 - C++

The only thing to add to Péter Török answer is that the Initializer List is the only way to initialize const members of objects, i.e.:

class foo
{
public:

    foo(int value)
        : myConstValue(value)
    {};

    foo()
    {
        myConstValue = 0; // <=== Error! myConstValue is const (RValue), you can't assign!
    };

private:
    const int myConstValue;
}

Solution 4 - C++

In your example code, the first one in constructor initialization and second one is assignment inside constructor body.

Constructor initialization list is the best way to do all member initialization because it improves performance.

class A
{
string name;
public:
A(string myname):name(myname) {}
}

In above case compiler will not create a temporary object to do the initialization. However in the following case:

A::A()
{
    name = myname;
}

A separate temporary object is created, and this temporary object is passed to string's assignment operator to assign to name. Then the temporary object is destroyed, which is not quite efficient.

Note: It is mandatory that a reference or a const member must be intialized in a constructor initialization list. They cannot be 'assigned' in the body of the constructor.

Solution 5 - C++

Apart from other answers, I would like mention that constructor initialization only for initialize member variables.

class Demo
{
	int a;
	int b;
public:
	Demo(int a,int b):a(a),b(b)
	{
	 
	}
	
};

if we initialize a and b inside constructor it would be self assignment.

Solution 6 - C++

First is initialization, using an initializer list and the second is default construction and then assignment. The first one is at least as fast as the second one and is preferable to the second one.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiongardian06View Question on Stackoverflow
Solution 1 - C++Luchian GrigoreView Answer on Stackoverflow
Solution 2 - C++Péter TörökView Answer on Stackoverflow
Solution 3 - C++PaperBirdMasterView Answer on Stackoverflow
Solution 4 - C++Sanish GopalakrishnanView Answer on Stackoverflow
Solution 5 - C++user4016479View Answer on Stackoverflow
Solution 6 - C++DumbCoderView Answer on Stackoverflow