C++返回值優化-Return Value Optimization
C++中的一些小細節比較多。這裏看下返回值優化。
代碼
using namespace std;
class RVO{
static int count__;
int id_;
public:
RVO(){id_=count__++;cout<<"constructor"<<id_<<endl;}
RVO(const RVO& r){id_=count__++;cout<<"copy"<<r.id_<<",my id:"<<id_<<endl;}
virtual ~RVO(){cout<<"destruct"<<id_<<endl;}
};
int RVO::count__=0;
RVO testRVO(){
return RVO();
}
//無優化時,testRVO函數等同於下面代碼
//RVO * f(RVO * _hiddenAddress) {
// RVO result;
// // copy result into hidden object
// *_hiddenAddress = result;
// return _hiddenAddress;
//}
//有優化時,testRVO函數等同於直接調用構造函數。也有的寫成下面的形式,但是比較含糊。
// f(RVO * _hiddenAddress) {
// copy result into hidden object
//}
int main(int argc,char** argv){
RVO r=testRVO(); //沒有RVO,此處會有2次拷貝構造函數調用
return 0;
}
如果沒有返回值優化,註釋處會有2次拷貝構造函數調用。第一次是函數內部拷貝構造返回值臨時對象,第二次是用返回值臨時對象來拷貝構造外部的r。這樣的話開銷就比較大了。
測試
加上如下選項可以禁用返回值優化,就可以看到想要的結果了。
g++ -fno-elide-constructors test.cpp
g++ -O0 test.cpp //此處無效,禁用優化,並沒有禁用返回值優化選項
./a.out
constructor0
copy0,my id:1
destruct0
destruct1
g++ test.cpp
./a.out
constructor0
destruct0
當加上返回值優化後,直接就變成了構造函數調用。優化過後,效果上是一樣的,但是改變了原始的語義。