I think that it has a lot of information about it but I don\'t know how this is called. I cannot understand difference between next two strings of code:
Obje
Object obj();
is not an instantiation of object, it is a declaration of a function obj
which takes no arguments and returns an instance of Object
.
Object obj;
is a default initialization
, i.e. instantiation with implicit constructor (thus, default implicit constructor or user-defined non-explicit
constructor with no parameters), and this declaration calls implicit constructors of non-POD Object
members, and for POD-types it does not initialize them (they will not be zeroed). This is right for members of members of Object
and so on recursively.
Object obj{};
is a list initialization or aggregate initialization (if Object
is an aggregate). Those it called differently, for empty braces, behavior is the same: all members of POD-types are zero-initialized, and non-POD are default-initialized.
Object obj = Object();
theoretically is a two-step statement: 1) create temporary Object
instance; 2) then construct obj by copy constructor/move constructor/copy operator/move operator. But in practice it will be default-constructed with copy/move-elision in mind (it is enabled on all modern compilers by default even with all optimizations off, you must disable elision explicitly). Better do not use this variant.
Pre-Conclusion
Choose
Object obj;
or
Object obj{};
Choose first if you want fast initialization with no zeroifying its POD-members.
Choose second if you want to be sure that all its POD-members will be zero after instantiation of Object
.
Practically, before first reading from its members, the both variants have the same speed in runtime on all modern OSes.
So...
Conclusion
Use value-initialization:
Object obj{};
unless you need a realtime performance on exotic systems.
Object obj();
declares a function, not an object! This is an instance of the "Most Vexing Parse".
Object obj = Object();
requires Object
to have an accessible move constructor or copy constructor (although the compiler might end up eliding the move/copy).
Simple ways to just create an object include:
Object obj;
Object obj{};
Object obj();
Declares a function names obj
that returns a Object
and takes no parameters. This is generally not what you want.
Object obj = Object();
Declares an Object
named obj
then is copy initialized with a temporary default constructed Object
. You normally don't want to do this either unless you are resetting an object back to a default state.
Generally if you want to construct without calling a constructor you can use
Object obj;
//or
Object obj{};
Big difference.
The first one is a function prototype to a function taking no arguments and returning an Object.
The second one instantiates an Object by calling the default constructor. For the avoidance of doubt the assignment operator is not called.
Drop the parentheses in the first case to make the statements equivalent.