Reputation: 623
In this code operator =
is overloaded to control operator behaviour for class A
objects, and copy constructor was also declared to see if it was used for the copying process.
My question is, what does the compiler use to copy the return object of a_object + b_object
into c_object
if copy constructor and assignment operator was not used as shown in the output? And how to control the behaviuor of copying in this case?
#include <iostream>
#define PUTLINE(X) std::cout<<X<<"----------------------------\n" ;
class A{
int value ;
public:
A(int v = 0) : value(v) {}
A(const A & a)
{
std::cout << "copy constructor...\n" ;
value = a.value ;
}
const A & operator = (const A & a) {
std::cout << " = operator... \n" ;
this->value = a.value ;
return *this ;
}
const A operator + (const A & a) {
return A(value + a.value) ;
}
void print(std::ostream & os) {
os << value << std::endl ;
}
};
int main () {
A a_object(10);
A b_object(20);
PUTLINE(1);
A c_object = a_object + b_object ; // what does the compiler use to make this copy?
PUTLINE(2);
A d_object = c_object;
PUTLINE(3);
c_object.print(std::cout);
PUTLINE(4);
d_object.print(std::cout);
PUTLINE(5);
a_object = c_object ;
PUTLINE(6);
a_object.print(std::cout);
}
Output looked like this:
1----------------------------
2----------------------------
copy constructor...
3----------------------------
30
4----------------------------
30
5----------------------------
= operator...
6----------------------------
30
Upvotes: 1
Views: 67
Reputation: 3556
a_object + b_object
is a function call. The return value is the value assigned to c_object
.
Upvotes: 0
Reputation: 171117
You're experiencing copy elision and return value optimisation (RVO). Under certain circumstances, the compiler is allowed to construct a returned object directly in the destination space, eliding the creation of a temporary and copying from it.
This is precisely what's happening in your case: the return value of operator+
is constructed directly in the space of c_object
using the (int)
constructor, so you don't see a call to the copy constructor.
With GCC, you can pass the command-line flag -fno-elide-constructors
, which prevents copy elision. Then you'll see all the copy constructor calls. Live example.
Upvotes: 3