If I understand correctly, value initialization T obj {};
uses the user-define constructor while default initialization T obj;
either uses the user-define constructor or leaves obj
uninitialized (i.e. undefined).
Since having uninitialized values is in general bad style, should we always prefer value initialization over default initialization? Is there any scenario where default initialization is actually better than value initialization?
CodePudding user response:
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 initializationT 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 determinate value, you can use default initialisation (T obj
) instead of value initialisation (T obj{}
) to buy some computation power.
CodePudding user response:
One key difference between value-initialization and default-initialization is that value-initialization guarantees that an object is properly initialized with a default value, whereas default-initialization does not provide this guarantee. This means that value-initialization is safer and more reliable, because it ensures that an object is always in a well-defined state.
Another difference between value-initialization and default-initialization is that value-initialization can be used to initialize objects of any type, including built-in types, user-defined types, and abstract types, whereas default-initialization is only applicable to objects of non-abstract types. This means that value-initialization is more versatile and flexible, because it can be used in a wider range of situations.
Overall, the choice between value-initialization and default-initialization depends on the specific needs and requirements of the situation. In general, value-initialization is a safer and more reliable way to initialize objects, but it may require more code and may not be applicable in all cases. Default-initialization is a simpler and more concise way to initialize objects, but it can lead to unpredictable behavior if the object is not properly initialized.
CodePudding user response:
Yes, you are correct that value initialization with T obj {}; will always use the user-defined constructor to initialize the object, while default initialization with T obj; may either use the user-defined constructor or leave the object uninitialized (i.e. with an indeterminate value).
In general, it is good practice to avoid using uninitialized values, as they can lead to undefined behavior in your program. Therefore, you should prefer value initialization over default initialization whenever possible.
There are a few scenarios where default initialization may be necessary or desirable, however. For example, if you are declaring a large array of objects and want to initialize each element with the default constructor, default initialization can be more efficient than value initialization, because it does not require calling the user-defined constructor for each element. In this case, default initialization can be a useful optimization.
Another scenario where default initialization may be useful is when you are declaring a class or struct that contains other objects as members, and you want to initialize the member objects with their default constructors. In this case, default initialization can be useful because it allows you to initialize the member objects without explicitly calling their default constructors in the class or struct's initializer list.
Here is an example of how default initialization can be used in this way:
struct MyStruct {
int a;
std::string b;
std::vector<double> c;
};
int main() {
// Use default initialization to initialize the member objects
// with their default constructors
MyStruct s;
// s.a will be uninitialized (i.e. indeterminate)
// s.b will be initialized to the empty string
// s.c will be initialized to an empty vector
}
In this example, the MyStruct struct contains three member objects - an int, a std::string, and a std::vector. When we declare an instance of MyStruct using default initialization, the int member a will be left uninitialized, while the std::string member b and the std::vector member c will be initialized with their default constructors.
Overall, while default initialization can be useful in some cases, it should generally be avoided in favor of value initialization, to ensure that your objects are always properly initialized and avoid undefined behavior in your program.
CodePudding user response:
Value initialization
is generally preferred over default initialization because it guarantees that the object is properly initialized with a defined value. This is particularly important for built-in types, such as integers and floats, which have undefined values when default-initialized.
For example, the following code will print the value 0
when using value initialization, but it may print an undefined value when using default initialization:
int a {}; // value initialization
std::cout << a << std::endl;
int b; // default initialization
std::cout << b << std::endl;
Value initialization is also preferred because it is less error-prone and more consistent than default initialization.
For example, the following code will compile and run without any issues when using value initialization, but it will produce a compile-time error when using default initialization:
struct S {
S() {}
};
int main() {
S s1 {}; // value initialization
S s2; // default initialization - compile-time error
return 0;
}
Therefore, it is generally recommended to use value initialization
over default initialization in C .