This question already has answers here:
Does the default constructor initialize built-in types?
(7 answers)
What happens when you define an empty default constructor?
(2 answers)
Closed 1 year ago.
Is there any difference regarding the initialization of the x member variable in these cases:
struct A {
int x;
A() {}
};
struct B {
int x;
B() : x(0) {}
};
struct C {
int x;
C() : x() {}
};
For all these cases, in the tests I did, x is always set to the initial value of 0. Is this a guaranteed behavior? Is there any difference in these approaches?
For B::B(), x is direct-initialized as 0 explicitly in member initializer list.
For C::C(), x is value-initialized, as the result zero-initialized as 0 in member initializer list.
On the other hand, A::A() does nothing. Then for objects of type A with automatic and dynamic storage duration, x will be default-initialized to indeterminate value, i.e. not guaranteed to be 0. (Note that static and thread-local objects get zero-initialized.)
Related
This question already has answers here:
C++11 member initializer list vs in-class initializer?
(3 answers)
Closed 2 years ago.
If I want to assign a default value to an instance variable, which method is to be preferred?
Is there a difference?
Class Foo {
int x = 0;
};
Class Foo {
int x;
Foo() : x(0) {}
};
You may choose to setup an initialization strategy for the member variable both using designated member initializers as well as member initializer list in constructors. If a given constructor does not initialize a given non-static data member, initialization of that data member will fall back on a designated member initializer, if present.
#include <iostream>
template<std::size_t TAG_N> struct Tag{};
struct Foo {
int x{42};
// ^^^^ - designated member initializer (DMI)
Foo() {} // Use DMI -> x is 42
Foo(Tag<0>) {} // Use DMI -> x is 42
Foo(Tag<1>) : x(1) {} // Initialized in mem. init list -> x is 1.
};
int main() {
std::cout << Foo{}.x << " "
<< Foo(Tag<0>{}).x << " "
<< Foo(Tag<1>{}).x << "\n";
// 42 42 1
}
Choosing which approach would enter the domain of opinion-based, but favoring consistency is never a bad advice, and [opinionated] many industry experts recommend using designed member initializers in classes which provide more than one constructor, to avoid the pitfall of e.g. adding a new member to the class but forgetting to initialize it in one the overloaded constructors' member initializer lists.
This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 4 years ago.
#include <iostream>
using namespace std;
class A{
public:
int a;
A() {a=0;}
A(int b) {a=b+1;}
};
class B{
public:
A a;
B():a(0) {}
};
int main(void) {
B *b = new B();
cout<<b->a.a<<endl;
return 0;
}
I replaced B():a(0) {} by B() {A(0)} and output changed from 1 to 0. I am wondering what's the difference between them?
B() : a(0) {} explicitly initializes the member B::a with the value 0. This is an example of a member initializer list. Basically, a(0) in this context calls a's constructor with the argument 0, which calls A::A(int), which, by your implementation, adds 1 to the argument and assigns the result to A::a. Thus in the first case, b->a.a == 1.
On the other hand, B() {A(0);} default-initializes B::a (because A has a default constructor) and creates a nameless local temporary object A(0); which is destroyed immediately without changing anything. It is functionally equivalent to B(){}, which is does nothing at all. You can omit this trivial constructor because the compiler can implicitly generate it for you. See special member functions for more information on how this works and under what conditions. Thus in the second case, you are calling the default constructor, which sets b->a.a == 0.
This question already has answers here:
Is there a way to make a C++ struct value-initialize all POD member variables?
(3 answers)
Closed 1 year ago.
I have a struct that only has double member variables, e.g.
struct foo { double a, b, c; };
Another class has a std::vector<foo> v member that calls the std::vector<foo>::vector(size_t) constructor in the initializer list.
What I'd like to do is write a default constructor for foo so that all the doubles in it are initialized to zero, without having to write
foo(): a(0), b(0), c(0) { }
I keep needing to add more variables to foo, but it doesn't make sense to have them be elements of a container like std::array<double>, because they all serve distinct purposes.
Since you've tagged this as C++14, you can initialize member variables like this without having to initialize them in a constructor:
struct foo {
double a = 0.0;
double b = 0.0;
double c = 0.0;
};
This question already has answers here:
In this specific case, is there a difference between using a member initializer list and assigning values in a constructor?
(12 answers)
Closed 7 years ago.
While I was working in c++ I see two type of ctor definition.. Is there any difference while assigning value? Does one of them has advantages or just writing style ?
1st ctor definition:
class X
{
public:
X(int val):val_(val){}
private:
int val_;
};
2nd ctor definition:
class X
{
public:
X(int val)
{
val_ = val;
}
private:
int val_;
};
Technically yes, although you can typically not observe any difference for built-in types like int.
The difference is that your first snippet copy-constructs val_ from val, while the second one default constructs val_ and then assigns val to it. As I said above, this usually only matters for more complex types whose constructors actually do work.
A simple example which demonstrates the difference would be
class X
{
public:
X(int val):val_(val){}
private:
const int val_;
};
which compiles vs.
class X
{
public:
X(int val)
{
val_ = val;
}
private:
const int val_;
};
which does not.
Yes there is a difference. In a constructor initializer list, the member variables are constructed, while the assignments in the constructor body is assignments to already constructed variables.
For the basic types like int or float it's no actual difference though.
In your example, there is no difference. Since your member is an int, the two statements have the same effect.
If your member variable was an object, the first form would be better, because it would simply call the constructor of the object class, while the second form would create an object by using the default constructor, then create another, store it into a temporary, call the destructor on the first object, copy the temporary into your member variable, call the destructor again on the second object.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ initialization lists
What is the difference between member-wise initialization and direct initialization in a class?
What is the difference between the two constructors defined in the class?
class A
{
public:
int x;
int y;
A(int a, int b) : x(a), y(b)
{}
A(int a, int b)
{
x = a;
y = b;
}
};
The theoretical answers have been given by other members.
Pragmatically, member-wise initialization is used in these cases :
You have a reference attribute (MyClass & mMyClass) in your class. You need to do a member-wise initialization, otherwise, it doesn't compile.
You have a constant attribute in you class (const MyClass mMyClass). You also need to do a member-wise initialization, otherwise, it doesn't compile.
You have an attribute with no default constructor in your class (MyClass mMyClass with no constructor MyClass::MyClass()). You also need to do a member-wise initialization, otherwise, it doesn't compile.
You have a monstruously large attribute object (MyClass mMyClass and sizeof(MyClass) = 1000000000). With member-wise initialization, you build it only once. With direct initialization in the constructor, it is built twice.
First one uses initialization and second one does NOT use initialization, it uses assignment. In the second one, the members x and y are default-initialized first (with zero), and then they're assigned with a and b respectively.
Also note that in the second one, members are default initialized only if the types of members are having non-trivial default constructor. Otherwise, there is no initialization (as #James noted in the comment).
Now see this topic to know:
What is a non-trivial constructor in C++?