本文是Inside The C++ Object Model Chapter 2 部分的讀書筆記。是討論編譯器調用拷貝構造函數時的策略(如何優化以提升效率),侯捷稱之爲"程序轉化的語義學"ide
或者說是是關於編譯器對於程序是如何進行有效轉化或者說翻譯,以實現C++的語法機制。主要來講有如下幾種Semantics:函數
1) 明確的初始化操做(Explicit Initialization)優化
好比定義: X x0;
那麼如下定義: X x1(x0); X x2 = x0; X x3 = X(x0); 都會被轉化成: X x1,x2,x3; 在這裏編譯器並不會作這三個object的初始化,而是調用copy constructor進行初始化:.net
x1.X::X(x0); x2.X::X(x0); x3.X::X(x0);翻譯
2) 參數初始化(Argument Initialization)設計
C++ Standard ( Section 8.5)說,把一個class object 當作參數傳遞給一個函數或者把它做爲一個函數的返回值時,至關於如下形式的初始化操做:ip
X xx = arg;其中xx是形式參數或者返回值,arg表明真正的參數值,所以相似於void foo(X x0);這種調用,將會使得local instance x0以memberwise的形式以實際參數爲初始值進行初始化。ci
通常來講,編譯器有兩種作法:get
a) introduce a temporary object編譯器
仍是以上文的函數聲明 void foo(X x0);
調用進入後,一、編譯器生成一個temporary object:X _temp;
二、以實際參數xx 拷貝構造 這個temporary object:_temp.X::X(xx);
三、從新改寫函數調用操做,foo(_temp);
四、最重要的一點就是修改參數調用方式爲引用,不然如何工做又回到原點啦。。。void foo(X &x0);
b) 將參數直接以copy constructor建構到函數的堆棧上,這樣也會有一個local object生成;固然在函數返回時該local object也會被destructed。
3) 返回值的初始化(Return Value Initialization)
當返回值是object時,這個object是如何返回的呢?cfront使用的是一個雙階段轉化:
a) 首先加上一個額外的參數,是class object的reference,這個參數將放置經過copy constructor得來的返回值
b)在return以前安插一個copy constructor,以便將欲傳回之的object當作上述新增參數的處置。
例如:X bar() { X xx; return xx;} 會被轉化爲:
void bar(X & _res) //這裏安插了臨時引用參數
{
X xx;
xx.X::X();
_res.X::X(xx); //這裏安插了臨時引用的拷貝構造函數
return;
}
如今編譯器必須轉化每一個bar調用,以反映其新定義。例如X xx = bar(); ===> X xx; bar( xx );
而相應的 bar().memfunc(); //執行bar()所返回之X class object的member function
會被編譯器轉化爲:
X temp0;
(bar(temp0),temp0).memfunc();
在返回值優化上,Optimization at the User Level or Optimization at the Compiler Level。在User Level, 設計者須要建立不一樣的constructor,這樣object直接經過計算,而不須要copy constructor。這樣作若是在很是注重效率的場合可能比較有意義,可是缺少抽象。
在Compiler Level,如今廣爲認知的就是 Name Return Value(NRV)Optimization:
void bar(X & _res) //這裏安插了臨時引用參數
{
_res.X::X();
//直接操做_res
return;
}
也就是說,NRVO 省略了一次copy constructor的調用。可是若是copy constructor有side-effect的話,那麼這個優化就會有問題。
NRV優化仍是很重要,好比下面的代碼,若是沒有NRV將會有三次copy 構造,二次析構:
Type get(int I) { return Type(i); } Type t = get(1);
甚至有人認爲user defined copy constructor會阻止NRV的優化。更多討論能夠參見:關於編譯器對拷貝構造函數優化的問題再討論