private object initialization in another class

Why is o/p of this code not calling assignment operator?

In class B, A a; should call A::A() and then in initializer list at : B(A &a):a(a) , it should call Assignment operator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
using namespace std;
 
class A
{
    // data members of A
public:
    A()           { cout << "\n A's constructor"; /* Initialize data members */ }
    A(const A &a) { cout << "\n A's Copy constructor"; /* Copy data members */ }
    A& operator= (const A &a) // Assignemt Operator
    {
        // Handle self-assignment:
        if(this == &a) return *this;
 
        // Copy data members
        cout << "\n A's Assignment Operator";  return *this;
    }
};
 
class B
{
    A a;
    // Other members of B
public:
    B(A &a):a(a) {  cout << "\n B's constructor"; }
};
 
int main()
{
    A a;
    B b(a);
    return 0;
}


The o/p is :
A's constructor
A's Copy constructor
B's constructor
Last edited on
aseemgoyal wrote:
In class B, A a; should call A::A() and then in initializer list at : B(A &a):a(a) , it should call Assignment operator.

That's not how it works. When you list an object in the constructor's initialization list it means you are deciding which constructor should be used to construct the object. In your code you say a should be constructed using the copy constructor so that is what happens.

If the constructor was B(A &a):a(){ this->a = a; } or B(A &a){ this->a = a; } then it would work as you said. First a is constructed using the default constructor and then the copy assignment operator is called.
Last edited on
it should call

No, it should not.

Line 22 calls nothing. It merely declares that class B object contains a class A member object.

The purpose of the initializer list is to be able to call (base and member) constructors.

The old inefficient way, without initializer list:
1
2
3
4
5
6
B( const A & ca )
// : a() // implicitly there, default constructor call
{
  a = ca; // copy assignment
  cout << "\n B's constructor";
}


With initializer list:
1
2
3
4
5
B( const A & ca )
: a( ca ) // copy constructor call
{
  cout << "\n B's constructor";
}

@keskiverto
But, for object of Class B, first all members must be defined i.e. a.

Here is a sample run which clarifies it:http://ideone.com/HJa65W
No. Not defined. Constructed.

When creating an object of type Foo (we assume that memory has already been allocated for the entire Foo object), three operations will be done in order:
1. The base class (subobject) of Foo is constructed.
2. The member variables are constructed in the order they occur in the definition of Foo.
3. The body of the constructor of Foo is executed.

In other words:
The construction of subobject B::a does start after the construction of B object has started and completes before the body of B::B(A&) is executed.

The initializer list syntax allows us to pass a parameter to the construction of B::a, and the parameter that you do use makes the construction of B::a to use the copy constructor of A to construct the B::a.

If you want to call that action "defining the a", then you define the a with copy constructor of A. The a is created at that point in execution, not before.
@keskiverto
thanks for clearing the concept
Topic archived. No new replies allowed.