Reputation: 714
Let us consider the following classes
struct test1
{
int a;
int b;
test1() : a(0), b(0) {}
};
struct test2
{
int a;
int b;
test2() { a = 0; b = 0; }
};
Now, I know that test1()
constructor is the right way to initialize the data members of a class
, because in test2()
we are performing assignment and not initialization. My questions are:
test1()
constructor? If not, then how are these initialized?Upvotes: 35
Views: 21646
Reputation: 88
Constructor-initializers allow initialization of data members at the time of their creation.
Some programmers prefer to assign initial values in the body of the constructor. However, several data types must be initialized in a constructor-initializer. The following lines summarizes them:
You cannot legally assign a value to a const variable after it is created. Any value must be supplied at the time of creation.
References cannot exist without referring to something.
C++ attempts to initialize member objects using a default constructor. If no default constructor exists, it cannot initialize the object.
Upvotes: 2
Reputation: 8758
A third variant utilizing direct-list-initialization. Advantages are
So this is less error-prone than both variants in the question:
#include <iostream>
class Test3
{
public: // Made public so we can easily output the vars. No struct is used to be consistent with question.
int a { 4 }; // No need for separate initialization in constructor.
int b { 2 }; // No need for separate initialization in constructor.
};
int main()
{
const auto t = std::move(Test3()); // Implicitly-declared default constructor + implicitly-declared move assignment operator
std::cout << t.a << t.b;
}
Output is 42
.
Upvotes: 7
Reputation: 894
For your example there is no real different because you are initializing plain integers.
But assume these integers are objects with constructors, then the compiler would generate the following calls:
// test1
a::copy_constructor(0);
b::copy_constructor(0);
// test2
a::default_constructor();
b::default_constructor();
a::operator = (0);
b::operator = (0);
So depending on your objects test2 could have a huge performance impact. Also by initializing your objects in the initializing lists guaranties that your variables have the data when you enter the constructor. One 'drawback' of the initializer list is that the it is executed in the order that the variables are declared and not in the order of the initializer list, so it could be that you don't want to use the initializer list.
Upvotes: 20
Reputation: 254751
What might go wrong if we perform assignment instead of initialization?
Some class types (and also references and const
objects) can't be assigned; some can't be default-initialised; some might be more expensive to default-initialise and reassign than to initialise directly.
Doesn't the compiler internally performs assignment in case of test1() constructor? If no then how are these initialized?
In the case of primitive types like int
, there is little or no practical difference between the two. Default-initialisation does nothing, and direct-initialisation and assignment both do essentially the same thing.
In the case of class types, default-initialisation, assignment and direct-initialisation each call different user-defined functions, and some operations may not exist at all; so in general the two examples could have very different behaviour.
Upvotes: 32