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"?
Initialization lists. In fact, constructors should initialize as a rule all member objects in the initialization list.
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.
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.
Conclusion: All other things being equal, your code will run faster if you use initialization lists rather than assignment.
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) {} };
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 ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With