wm 50
wm 50

Reputation: 27

Why is my C++ program's copy constructor called twice?

I can't figure out why my output start with "ACCB.." - my expectation was "ACB.."

Why is the copy constructor of class A called twice?

#include <iostream>
    
using namespace std;
    
class A
{
    int x, y, z;
public:
    A(int x, int y, int z) :x(x), y(y), z(z) { cout << "A"; }
    A(A& a) :x(a.x), y(a.y), z(a.z) { cout << "C"; }
    void sh() { cout << x << y << z; }
};
    
class B
{
    A a;
    int q, r;
public:
    B(A x, int y, int z) : a(x), q(y), r(z) { cout << "B"; }
    void sh() { a.sh(); cout << q << r; }
};
    
int main()
{
    A i(9, 7, 4);
    B b(i, 3, 7);
    b.sh();
}

Upvotes: 0

Views: 80

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 596206

Your copy constructor is being called 2 times because you are making 2 copies. 1 is being made implicitly by the compiler, and 1 is being made explicitly in your own code.

In your B constructor, its x parameter is being passed by value. That is an implicit copy being made when i in main() is assigned to x. Then, an explicit copy is made when x is passed to the copy constructor of the a member of B.

You can eliminate the implicit copy by changing the x parameter to be passed by reference instead.

Also, your A copy constructor should be declared as A(const A& a).

#include <iostream>
using namespace std;

class A
{
    int x, y, z;
public:
    A(int x, int y, int z) :x(x), y(y), z(z) { cout << "A"; }
    A(const A& a) :x(a.x), y(a.y), z(a.z) { cout << "C"; }
    void sh() { cout << x << y << z; }
};

class B {
    A a;
    int q, r;
public:
    B(const A& x, int y, int z) : a(x), q(y), r(z) { cout << "B"; }
    void sh() { a.sh(); cout << q << r; }
};

int main()
{
    A i(9, 7, 4);
    B b(i, 3, 7);
    b.sh();
}

Upvotes: 3

Adrian Mole
Adrian Mole

Reputation: 51825

Why copy constructor of class A is called twice?

Because your B constructor takes its first argument (an object of class A) by value - so a copy of i is made, which is then passed to the constructor.

To prevent this, declare the first argument to the B constructor as a reference (as in the A copy constructor itself):

    B(A& x, int y, int z) : a(x), q(y), r(z)
    {
        cout << "B";
    }

Upvotes: 1

Related Questions