T obj;
either uses the user-define constructor or leaves obj uninitialized (i.e. undefined).
obj
in this case is initialised. Moreover all non-static members of class type are also default-initialised and only non-static members of built-in types (pointers, int
, char
, etc...) are left with indeterminate value. That means that required memory is allocated for those members anyway, but no extra effort was done to set them to any specific value (my personal analogy from C programming language is malloc
vs calloc
functions).
T obj {};
uses the user-define constructor while default initialization T obj;
either uses the user-define constructor or leaves obj uninitialized
If a user defined constructor is provided, both default initialisation and value initialisation ({}
) invoke the same constructor and have the same effect (depending on how the constructor is implemented).
If there is no user-defined default constructor (or it's defined with default
keyword) and no constructors that take a std::initializer_list
parameter then value initialisation ({}
) ensures that all non-static members are value-initialised, while default initialisation ensures that the members are default-initialised (for primitives it means their value is indeterminate).
should we always prefer value initialization over default initialization?
Zero-initialisation is an additional computation, and in C++ you don't pay for what you don't use, so in case you don't need some parts of your class to have determinate value, you can use default initialisation (T obj
) instead of value initialisation (T obj{}
) to buy some computation power.