Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About constructors and assign operators in C++

Tags:

c++

I simply created a class like this:

class GreatClass
{
public:
    GreatClass(){cout<<"Default Constructor Called!\n";}
    GreatClass(GreatClass &gc){cout<<"Copy Constructor Called!\n";}
    GreatClass(const GreatClass &gc){cout<<"Copy Constructor (CONST) Called!\n";}
    ~GreatClass(){cout<<"Destructor Called.\n";}
    GreatClass& operator=(GreatClass& gc){cout<<"Assign Operator Called!";return gc;}
    const GreatClass& operator=(const GreatClass& gc){cout<<"Assign Operator (CONST) Called!";return gc;}
};

GreatClass f(GreatClass gc)
{
    return gc;
}

and in main() function, there are two versions:

version #1:

int main()
{
    GreatClass g1;
    GreatClass G = f(g1);
}

version #2:

int main()
{
    GreatClass g1;
    f(g1);
}

They all generates the SAME output:

Default Constructor Called!
Copy Constructor Called!
Copy Constructor Called!
Destructor Called.
Destructor Called.
Destructor Called.

I do not understand why there is nothing happening when I'm assigning f(g1) to G. What constructor or operator is called at this point?

Thanks.

like image 659
Renfei Song Avatar asked Jul 01 '13 16:07

Renfei Song


1 Answers

Compiler implementations are allowed to elide/remove copy constructor calls in certain cases, the example you specify is a good example use case of such a scenario. Instead of creating a temporary object and then copying it to destination object the object is created directly in the destination object and the copy constructor call is removed out.

This optimization is known as Copy elision through Return value optimization.

Also, with C++11 move semantics through rvalue references might kick in instead of the Copy semantics. Even with move semantics the compilers are still free to apply RVO.

like image 126
Alok Save Avatar answered Oct 21 '22 09:10

Alok Save