函数返回临时对象时,有没有进行拷贝?会不会调用拷贝构造函数?
以下两段代码的区别只是一个显式定义了拷贝构造函数,一个没有定义,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方式进行编译的
首先,我用g++不能編譯你的程式碼,
A& a = fn();
這一句報錯:用型別為‘A’的右值初始化型別為‘A&’的非常量引用無效。把引用去掉後(
A a = fn();
)發現還是沒有呼叫copy constructor。網路上查了一下發現這叫“copy elision”,就是說copy constructor即使有副作用還是會被編譯器優化掉的。一般都會被優化掉, 有可能即使你沒有開優化選項.
這是進步, 有缺陷的東西, 為什麼還要保留呢. 優化才是正確的選擇.
參考這個回答關於c++11move copy contructor