youssef
youssef

Reputation: 623

How to control the copy of return object into a new object?

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

Answers (2)

Matthias
Matthias

Reputation: 3556

a_object + b_object is a function call. The return value is the value assigned to c_object.

Upvotes: 0

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

Related Questions