问题描述
函数返回临时对象时,有没有进行拷贝?会不会调用拷贝构造函数?以下两段代码的区别只是一个显式定义了拷贝构造函数,一个没有定义,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 created0079FC7B call fn0079FC7B 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 created00EFF94B destroied00EFF967 call fn00EFF967 destroied
已找到没有调用拷贝构造函数的可能原因:使用Release方式进行编译的
问题解答
回答1:首先,我用g++不能编译你的代码,A& a = fn();这一句报错:用类型为‘A’的右值初始化类型为‘A&’的非常量引用无效。
把引用去掉后(A a = fn();)发现还是没有调用copy constructor。网上查了一下发现这叫“copy elision”,就是说copy constructor即使有副作用还是会被编译器优化掉的。
回答2:一般都会被优化掉, 有可能即使你没有开优化选项.这是进步, 有缺陷的东西, 为什么还要保留呢. 优化才是正确的选择.
回答3:参考这个回答关于c++11move copy contructor