I know this is not a new feature of C++11 but it has been enhanced.
And I've never quite understood the reasoning. It seems that it
is preferable to use initialisation in a Constructor rather
than assignment:
1 2 3 4 5 6
class C{
private:
int n;
public:
C(int j): n{j}{};
};
Rather than
1 2 3 4 5 6
class C{
private:
int n;
public:
C(int j){n=j;};
};
Why is the former better? To me it just seems to add yet more
syntactic clutter for no obvious benefit.
EDIT: The best I can figure is that even though your assignment is in a class header, the variable n still does not equal j until run-time.
With initialization, the variable equals j at compile-time. --[Thank you JLBorges].
There are some equations that can be done at compile time that might exponentially speed up program execution by putting the stress on the compiler ( https://en.wikipedia.org/wiki/Memoization ), and initializing the variable might make it usable at compile-time if needed.
Memoization: cheating by knowing the answer before the question is asked.
The reason is simple. In the first example only the constructor is called. In the second example if n had a construct it is called first then the content is changed.
This saves processor time: One action in place of two.
Sorry #coder777, I'm still not getting it. If n had a constructor surely it would still need to be called in both cases?
#newbleg, I'll need to look into the limitations of initialization but memoization might be a valid use-case if initialization is limited to compile time expressions only. Although in that case wouldn't it limit the values that can be passed to the constructor by user code? ie How would the compiler be able to predict the values passed in other, separately compiled, modules?
For a member object with trivial initialisation (eg. int), there is no performance difference between direct initialisation and do-nothing-initialisation followed by assignment. In this case, the only advantage of initialisation over assignment is that it prevents 'use-before-giving-it-a-value' errors.
For member objects with non-trivial initialisation, there could be a performance impact. Constructing an object in a specific state is usually cheaper than default constructing the object and then following it up with assigning to the already constructed object.
#include <iostream>
struct A
{
int value ;
explicit A( int v = 0 ) { value = v ; std::cout << "A::constructor, " ; }
A& operator= ( int v ) { value = v ; std::cout << "A::assignment\n" ; return *this ; }
};
struct B1
{
A a ;
explicit B1( int v ) : a{v} { std::cout << "body of B1::constructor\n" ; }
};
struct B2
{
A a ;
explicit B2( int v ) { std::cout << "body of B2::constructor, " ; a = v ; }
};
int main()
{
B1 b1{7} ; // A::constructor, body of B1::constructor
B2 b2{7} ; // A::constructor, body of B2::constructor, A::assignment
}
> With initialization, the variable equals j at compile-time.
No. That is guaranteed to be the case only if
1. the constructor is constexpr
and 2. the value passed to the constructor is a constant known at compile time.
OK, Experiments complete and I think I get it now.
Basically it only really matters when the members are classes.
The issue is that the member constructors are called before the outer class constructor so if you try to use assignment you do two operations on the member instead of one. Also for const and reference members as well as copy constructors its the only way to properly construct the members.
So in summary: using initialisation rather than assignment is more efficient, guarantees copy constructors get called and is the only way to initialize const and reference members. And since there is no performance penalty you might ass well use it for non class members too.