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++?
Related
This question already has answers here:
Constructor initialization-list evaluation order
(3 answers)
Closed last year.
Can I safely use members to initialize others?
class Class {
public:
Class(X argument) : memberA(argument), memberB(memberA) {}
A memberA;
B memberB;
};
Here we use the argument to the constructor to initialize memberA. We then rely on the fact that this happens before the initialization of memberB and initialize memberB using memberA.
If we assume X, A, and B to be std::string the above example works (tested with gcc), as long as we do not change the order in which the members are declared. But is this actually guaranteed by the standard or am I abusing an implementation detail of the compiler?
Yes, this is safe as per class.base.init#15
The expression-list or braced-init-list of a mem-initializer is in the function parameter scope of the constructor and can use this to refer to the object being initialized.
This Note also has an example with this->i to show that previously initialized class members can be used to initialize other class members inside a mem-initializer. (The this-> is only necessary in this example to disambiguate the member and the constructor parameter, both named i).
Be careful that the member is already initialized before using it, since from class.base.init#13.3
... non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).
This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
No matching function for call to Class Constructor
(5 answers)
Closed 5 years ago.
I have a class called A.
It has an instance or B:
public:
B inst;
B's constructor is like B::B(int, int).
When creating the A class's constructor A::A() { }, it gives me the following error:
No matching function for call to B::B()
when I haven't created or mentioned any B in A's constructor. Any idea?
Constructing A requires all of A's data members to be constructed. In this case, B must be default-constructed as you did not provide a member initialization list. As B defines a non-default constructor, generation of its implicit default constructor is suppressed - that's why you're getting the error.
When class A contains an instance of class B, constructing an instance of A also requires construction of the contained instance of B.
If no constructor of B is listed in the initialiser of class A, the default is to invoke a constructor of B that accepts no arguments. For example
class A
{
public:
A::A() {};
private:
B b;
};
is functionally equivalent to
class A
{
public:
A::A() : b() {};
private:
B b;
};
This involves a constructor of B with no arguments. If no such constructor exists, the result is a diagnostic (error message). Since you have declared/defined a constructor with arguments, a constructor for B with no arguments is not implicitly generated.
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 10 years ago.
Possible Duplicate:
Initializing in constructors, best practice?
Advantages of using initializer list?
I have the following two ways to define the constructor in the Point Class :
class Point
{
public :
Point(double X,double Y):x(X),y(Y){}
Private :
double x,y;
}
Another way :
class Point
{
public :
Point(double X,double Y)
{
x= X;
y = Y;
}
Private :
double x,y;
}
I want to know which one is better and why?Is there is the use of copy ctor in the first case?
Where each one is preferred?Can some explain with the example?
Rgds,
Softy
Use initializer lists when possible. Although in this particular case it makes no difference, you'll get in the habit.
For POD types, the members don't get initialized twice so performance-wise it's the same thing. non-POD types are initialized before entering the constructor body, so they'll be initialized twice if you don't do it in the initializer list but in the body of the c-tor.
const members and references must be initialized in the initializer list. Again, doesn't apply to your case.
The second version does an assignment to the data members, whereas the first initializes them to the given values. The first version is preferred here. Although it may make little difference in the case of doubles, there is no reason at all to prefer a construction that performs extra operations. If your data members were not doubles, but types that are expensive to construct, you would be paying the penalty of default constructing them, and then assigning a value to them.
Example:
struct ExpensiveToConstruct { .... };
struct Foo {
Foo() {
// here, x has already been default constructed
x = SomeValue; // this is an assignment to the already constructed x.
}
ExpensiveToConstruct x;
};
struct Bar {
Bar : x(SomeValue) {
// only the constructor has been called. No assignemt.
}
ExpensiveToConstruct x;
};
Better to use initialize list in your ctor. It would be more efficient. In your 2nd way, ctor will initialize member data twice, with default value 1st, and then invoke statement in ctor.
and more, for const or reference member, should be initialized by init lists, cannot be initialized in ctor.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why should I prefer to use member initialization list?
Class A has a member variable i. i can be initialized or assigned during object creation.
A) Initialise
class A {
int i;
public:
A(int _i) : i(_i){}
}
B) assign
class A {
int i;
public:
A(int _i) : { i = _i}
}
My question is what is the basic difference between these 2 approach?
The difference lies in which C++ mechanism is used to initialize i in your class. Case (A) initializes it via constructor, and case (B) uses the assignment operator (or a copy constructor if no assignment operator is defined).
Most C++ compilers would generate exactly the same code for this particular example, because you're using int, which is a "plain old data" type. If i were a class type, it could make a great deal of difference.