函数返回临时对象时,有没有进行拷贝?会不会调用拷贝构造函数?
以下两段代码的区别只是一个显式定义了拷贝构造函数,一个没有定义,MSVC2013编译后运行的结果不同。但是可以从结果中看出,第一个并没有调用拷贝构造函数,到底是什么导致两者不同的结果呢?
代码一:
#include <iostream>
class A{
public:
A(){ std::cout << this << " created" << std::endl; }
~A(){ std::cout << this << " destroied" << std::endl; }
A(const A& a){ std::cout << "copy " << &a << " to " << this << std::endl; }// here is the difference
void fn(){ std::cout << this << " call fn" << std::endl; }
};
A fn()
{
A a;
return a;
}
int main()
{
A& a = fn();
a.fn();
return 0;
}
实际运行结果:
0079FC7B created
0079FC7B call fn
0079FC7B destroied
代码二:
#include <iostream>
class A{
public:
A(){ std::cout << this << " created" << std::endl; }
~A(){ std::cout << this << " destroied" << std::endl; }
void fn(){ std::cout << this << " call fn" << std::endl; }
};
A fn()
{
A a;
return a;
}
int main()
{
A& a = fn();
a.fn();
return 0;
}
实际运行结果:
00EFF94B created
00EFF94B destroied
00EFF967 call fn
00EFF967 destroied
已找到没有调用拷贝构造函数的可能原因:使用Release方式进行编译的
PHPz2017-04-17 14:47:37
First of all, I can’t compile your code using g++. A& a = fn();
This sentence reports an error: Initializing a non-const reference of type ‘A&’ with an rvalue of type ‘A’ is invalid.
After removing the reference (A a = fn();
), I found that the copy constructor was still not called. I checked online and found that this is called "copy elision", which means that even if the copy constructor has side effects, it will still be optimized away by the compiler.
天蓬老师2017-04-17 14:47:37
It will usually be optimized, even if you don’t turn on the optimization option.
This is progress. Why keep something with flaws. Optimization is the right choice.