0

I have a class in which i have defined:

  1. Constructor
  2. Destructor
  3. Copy constructor
  4. Assignment operator
  5. operator +(Class& obj) to add two objects.

operator+ returns by value as follows:

Base operator +(Base& obj2)
{ 
    cout<<"+ operator called\n"; 
    Base tmp;
    tmp.x=x+obj2.x;
    tmp.y=y+obj2.y;
    return tmp;
}

If in my main function I create three objects. There should be three destructor calls:

Base obj1(1,2);
Base obj2(1,2);
Base obj3=obj1+obj2; 

Questions:

  1. In the body of operator +(), while return tmp; i see it calls my copy constructor. Is it that this tmp of type Base is getting stored in a temporary object generated by compiler internally (e.g. Base compiler_tmp=tmp) and hence the copy constructor is called?

  2. If yes, then i suppose it should represent the RHS of the expression obj3=obj1+obj2; and the destructor should be called at the end of this statement.

Are my above assumptions correct? Or I am missing a point here?

Les
  • 10,335
  • 4
  • 40
  • 60
anurag86
  • 1,635
  • 1
  • 16
  • 31
  • 4
    Related - http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization - maybe a dupe? – Luchian Grigore Sep 17 '15 at 14:54
  • Slightly off-topic: Any reason why you're not passing obj2 by *const* reference in your operator + implementation? The operator function itself should also be marked as *const* because there is no reason why invoking operator on an instance should have to modify that instance. – antred Sep 17 '15 at 15:04
  • @antred: yes its a good programming practise to write const &. But not a rule. I was just trying all the combinations to see when exactly is copy constructor called and when(and which point) destructor is called. So you can pass by value or address while collecting you can collect it as by value or by ref or by const ref. – anurag86 Sep 17 '15 at 15:07
  • 1
    @antred: Because it is a [local variable](http://stackoverflow.com/questions/4382440/c-operator-and-operator-overloading) that might be destroyed after the return of `operator+`. So you might end up having a reference to a variable which does not exist anymore. – Gombat Sep 17 '15 at 15:11
  • 1
    @Gombat, @antred talks about passing `obj2` by reference, not about returning by reference. – Petr Sep 17 '15 at 15:13
  • You have 'Base obj1(1,2);' twice. Nevermind, fixed it. – Les Sep 17 '15 at 15:40
  • This may be compiler specific, but on VS2013, the call to the copy constructor you reference in #1 is copying 'tmp' directly to 'obj3'. There is no extra hidden copy to have to destruct. (look at the addresses of the objects in the debugger) – Les Sep 17 '15 at 16:28
  • @Les: actually i found _return tmp_ calls copy constructor and it must be getting destroyed in main() at the end of execution of the expression obj3=obj1+obj2 because i see one extra destructor call. – anurag86 Sep 17 '15 at 16:35
  • @anurag86: I agree your copy constructor is being called, but it is being called on 'obj3' and being passed 'tmp', look at your debugger and compare the addresses. The one extra destructor is probably for 'tmp'. – Les Sep 17 '15 at 16:52

2 Answers2

1

The question is two-fold. There are semantic copy-construction, real copy-construction and move-construction (which you didn't define). Semantically, you have following copy-constructors invoked in the course of function execution:

  • return tmp; copy-constructs an object in 'function return space' (whatever it is) from your tmp
  • temporary in obj3 = is copy-constructed from object in function return space
  • obj3 is copy-constructed from the temporary

Now, copy-elision techniques come into play. Depending on your compiler, you might have any number of those copy-constructors not called.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • @SegeyA : I agree with the 1st point. However 1st and the 2nd point points to the same thing. The return of the object by value calls copy contructor(which gets called due to copy of this object tmp to temporary object which is represented by the expression (obj1+obj2) ). So point 2 - there is no additional copy constructor call. For point 3 the assignment operator would be called(not the copy constructor) – anurag86 Sep 17 '15 at 15:33
  • @anurag86 - For point 3, the OP shows a declaration, so shouldn't the copy constructor be called instead of the operator= ? – Les Sep 17 '15 at 15:39
  • @Les : Oh yes you are right. I pasted Base Obj3=Obj1+Obj2 in the example here on stackoverflow but was trying Base Obj3; obj3=obj1+obj2. Thanks for pointing it out. – anurag86 Sep 17 '15 at 16:32
  • @anurag86, no. There are semantically two copies when objects are returned from the function - to 'return space' and from 'return space'. – SergeyA Sep 17 '15 at 17:05
0
  1. Yes. operator+ calls the copy constructor since you return a new instance of Base.

  2. Right.

Gombat
  • 1,994
  • 16
  • 21