Copy constructor invoked 2 times, not 3 as expected?

118 Views Asked by At

Here is one program taken from a textbook featuring copy constructors:

#include <stdio.h>
#include <conio.h>
#include <iostream>

using namespace std;

class point
{
    private:
        int x,y;
    public:
        point(int ox =0, int oy =0)
        {
            cout << " Make object" << this << endl;
            cout << " Using default constructor \n";
            x = ox, y = oy;
        }
        point(const point &p)
        {
            cout << " Make object" << this << endl;
            cout << " Using copy constructor \n";
            x = p.x, y = p.y;
        }
        void move(int dx, int dy);
        void display();
};

point fct(point a);

int main()
{
    point a(5,2);
    a.display();

    point b = fct (a);
    b.display();
    getch();
    return 0;
}

void point::move(int dx, int dy)
{
    x += dx, y += dy;
}

void point::display()
{
    cout << "Coordinates :" << x << " " << y << "\n";
}

point fct(point a)
{
    point b=a;
    //b.move(2,3);
    return b;
}

It should be noted that the copy constructor is of the form : point (const point &p) instead of point (point &p) (the latter is what's in the textbook, but couldn't compile so I had to switch to the first one, but still I can't understand why :( )

The textbook said that there will be 3 lines of "Using copy constructor" , corresponding to 3 calls to the copy constructor. I think the reason for that is, when you call: b = fct(a)

  1. The function "fct" makes a copy of a (pass-by-value), therefor one call

  2. The line : point b = a : again, a copy constructor is invoked

  3. The return value is then copied into b (the variable in main, not the one in fct) this is 3rd one.

However upon execution, there is only 2 calls. Can anyone give me a good explaination on this?

1

There are 1 best solutions below

2
On

Two copies occur because Named Return Value Optimization (NRVO) elides one of the copies.

point fct(point a)
{
    point b=a;
    return b;
}

point b = fct (a);

The first copy is the one from the argument a in main to the parameter a in fct. This occurs because the point is taken by-value.

The second copy is from a to b inside func.

The copy which is elided is the one in returning b by value. In this case, b can be directly allocated into the b at the call site, so no copy takes place.