Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing fields in constructor - initializer list vs constructor body [duplicate]

Tags:

c++

parameters

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.

like image 474
gardian06 Avatar asked Mar 28 '12 07:03

gardian06


People also ask

Is assigned in constructor body consider performing initialization in initialization list?

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.

Does initializer list call copy constructor?

And if we use Initializer List there are only two function calls: copy constructor + destructor call.

What is the advantage of initializer list in C++?

The most common benefit of doing this is improved performance. If the expression whatever is the same type as member variable x_, the result of the whatever expression is constructed directly inside x_ — the compiler does not make a separate copy of the object.

Is constructor same as initializer?

Constructor is a special non-static member function of a class that is used to initialize objects of its class type. In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual bases and non-static data members.


2 Answers

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.

like image 162
Luchian Grigore Avatar answered Oct 06 '22 12:10

Luchian Grigore


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.

like image 25
Péter Török Avatar answered Oct 06 '22 12:10

Péter Török