Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Initialising fields directly vs initialisation list in default constructor

Tags:

I'd like to know if there is a difference between this code:

class Foo{  private:     int a = 0;  public:     Foo(){} } 

And:

class Foo{  private:     int a;  public:     Foo(): a(0) {} } 

And, if so, which should be preferred? I know it's preferable to use an initialiser list than assigning in the constructor body, but what about initialiser list vs directly initialising in field declaration (for primitive types, at least, as is the case here)?

Also, what of the case below:

class Foo{  private:    int a = 0;  public:    Foo(){}    Foo(int i): a(i) {} } 

When the non-default constructor is called: is "a" initialised twice, first to 0 then to "i", or directly to "i"?

like image 779
DasBoot Avatar asked Nov 02 '16 10:11

DasBoot


People also ask

Should my constructors use initialization lists or assignment?

Initialization lists. In fact, constructors should initialize as a rule all member objects in the initialization list.

What is initialization list in constructor?

Initializer List is used in initializing the data members of a class. The list of members to be initialized is indicated with constructor as a comma-separated list followed by a colon. Following is an example that uses the initializer list to initialize x and y of Point class.

What are the advantages of initializer list?

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 initialization list faster?

Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.


2 Answers

From cppreference - Non-static data members

Member initialization
1) In the member initializer list of the constructor.
2) Through a default member initializer, which is simply a brace or equals initializer included in the member declaration, which is used if the member is omitted in the member initializer list.

If a member has a default member initializer and also appears in the member initialization list in a constructor, the default member initializer is ignored.


To conclude, both initializers are equivalent and do what they are supposed to do.

I would prefer the default member initializer, if I'd use the default constructor anyway, or if all or most constructors would initialize the member to the same value.

class Foo { private:     int a = 0; }; 

If all constructors initialize the member to some different value however, using the default member initializer makes less sense, and then an explicit initialization in the respective constructors would be more clear

class Foo { private:     int a; public:     Foo() : a(3) {}     Foo(int i) : a(i) {} }; 
like image 134
Olaf Dietsche Avatar answered Nov 22 '22 10:11

Olaf Dietsche


The first set of examples are identical to each other.

For the last example, the C++ standard specifies as follows:

12.6.2 Initializing bases and members

[ ... ]

If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member’s brace-or-equal-initializer is ignored. [ Example: Given

struct A { int i = /∗ some integer expression with side effects ∗/ ; A(int arg) : i(arg) { } // ... }; 

the A(int) constructor will simply initialize i to the value of arg, and the side effects in i’s brace-or-equal-initializer will not take place. — end example ]

like image 25
Sam Varshavchik Avatar answered Nov 22 '22 09:11

Sam Varshavchik