Abhinav Vishak Abhinav Vishak - 1 month ago 10
C++ Question

Constructors with objects as parameters

Suppose I have a class as follows:

class A{
int x ;
A( int i ){
x = i ;
}
}


And I have another class B which has an instance of class A as an member object.

class B{
int y ;
A obj_a ;
B( int j , A a ){
y = j ;
obj_a = a ;
}
}


When I do the following :

int main(){
A obj1( 1 ) ; // obj.x has value 1
B obj2( 2 , obj1 ) ;
}


The 2nd line throws an error saying no function call of the form A::A(). I know this means that a default style constructor is missing , but why do I need this ? obj1 is created using the defined constructor so that isn't an issue.

My current line of thought is that
A a
and
obj_a = a
would invoke the copy constructor which is implicitly defined.

Note: I have excluded private,public etc for brevity.

Answer

An object must be fully consistent, all of its members constructed, by the time it enters the body of the constructor. So in

B( int j , A a ){
    y = j ; 
    obj_a = a ; 
}

before

{
    y = j ; 
    obj_a = a ; 
}

gets a chance to do anything, obj_a must have been constructed.

Since no instruction on how to construct obj_a has been provided with the Member Initializer List, obj_a will be built with the default constructor for class A. Class A has no default constructor, no A::A(), so the error is raised.

The solution is to use the Member Initializer List instead of assignment inside the body of the function. Not only does this save you construction of an object that will promptly be over written, the compiler also has more lee-way to optimize and you may get some other small improvements.

Class B should be:

class B{
    int y ; 
    A obj_a ; 
    B( int j , A a ): y(j), obj_a(a)
    {
    }
}
Comments