I have next code:
#include <iostream>
class Example
{
public:
Example()
{
std::cout
<< "constructor: "
<< std::hex
<< this
<< std::endl;
}
~Example()
{
std::cout
<< "destructor: "
<< std::hex
<< this
<< std::endl;
}
static Example foo()
{
Example ex;
std::cout
<< "foo: "
<< std::hex
<< &ex
<< std::endl;
return ex;
}
};
int
main()
{
Example ex = Example::foo();
}
Mingw compiled program says:
constructor: 0x22fe4f
foo: 0x22fe4f
destructor: 0x22fe4f
That is expected result for me programming only with wingw
and g++
But when I tried to use Microsoft cl
I got this:
constructor: 00000000001BF750
foo: 00000000001BF750
destructor: 00000000001BF750
destructor: 00000000001BF790
Two destructor calls? Only one constructor call? Ok, foo
create it's own object and call copy
constructor on return
. But why I need to copy it when compiler can put object in main
function stack like mingw and put out
pointer as argument to foo
function by itself?
Like this:
// no return but `out` reference
static void foo(Example &ex)
{
std::cout
<< "foo: "
<< std::hex
<< &ex
<< std::endl;
}
};
int
main()
{
Example ex; // allocate memory in stack
Example::foo(ex); // process/fill it
}
What's I do wrong or is there are any way to not call copy
constructor and not writting code with out
references?
Constructors are not the only way to create an object. A Copy Constructor
and Move Constructor
(C++11 Onwards) can do the same.
In your case, when the return ex
is executed, the instance created in the function is deleted and a new instance is created using Copy Constructor
. you will get the print if you write the following code
Example(const Example &) {
std::cout << "Copy Constructor" << std::hex << this << std::endl;
}
The copy happens before the destruction of original object and hence you'll see this print before destructor.
Why its not happening in some compilers?
Because of a mechanism called RVO (Return value optimization), the compiler intelligently understand that you'll be using the same instance and hence it's being moved instead of being copied.
Hope its clarifies.