Class Cents(){
int m_val;
public:
Cents(int x=0){ cout<<\"Constructor\";}
Cents(const Cents& src){ cout<<\"Copy constructor\"}
Cents Ad
This happens because most of the compilers perform Return Value Optimization (aka RVO) to save on copying.
This is an optimisation known as copy elision, sometimes called "(N)RVO" (for "(named) return value optimisation") by those who like acronyms.
In certain circumstances, when an object is (conceptually) created in one place, copied or moved to another, and then destroyed, the program is allowed to create it in its final place instead. This optimisation is allowed even if the elided constructor and/or destructor have side effects, as they do in your example.
Returning a temporary, or a local variable, from a function is one of these situations. Instead of creating temp
in the function's stack frame then copying it to the caller's, the program may instead create it directly in the caller's frame.
When you return *this
, the copy can't be elided, since *this
has a lifetime beyond the function. From the caller's point of view, there will be two objects, so the program must actually make a copy:
Cents original;
Cents copy = original.Add(42);
// "copy" and "original" both exist: the object must have been copied.
For full details of which operations can be elided by this optimisation, see the C++11 Standard, 12.8/31.