x x0;
void foo_bar()
把乙個class object當做引數傳給乙個函式(或者作為乙個函式的返回值),相當於以下操作:
x xx = arg;
其中,xx代表形式引數或返回值,arg為真正的引數值(即實參)。
下面這樣的呼叫方式:
// 已知foo函式的宣告
void foo(x x0);
x xx;
// ...
foo(xx);
將轉換為:
// c++偽碼
// 編譯器產生的臨時物件
x __temp0;
// 編譯器呼叫copy constructor
__temp0.x::x(xx);
// 重新改寫函式的呼叫操作,以便使用上述臨時物件
foo(__temp0);
已知如下的函式定義:
x bar()
bar()的返回值如何從區域性物件xx中拷貝過來?stroustrup在cfront中的解決方法是乙個雙階段優化:
1、首先加入乙個額外引數,型別是class object的乙個reference。該引數用來存放「拷貝構建」而得的返回值。
2、在return指令之前安插乙個copy constructor呼叫操作,以便將欲傳回object的內容當做上述新增引數的初值。
3、函式的返回值為return,不返回任何值。
有了這樣的演算法,bar()轉化如下:
// c++偽碼
void bar(x &__result)
練習一下:
1、x xx = bar(); 轉換為
// 不必施行default constructor ???
x xx;
bar(xx);
2、bar().memfunc();可能被轉化為:
// 編譯器產生臨時物件
x __temp0;
(bar(__temp0), __temp0).memfunc();
3、已知程式宣告了乙個函式指標:x ( *pf )(); pf = bar;,將被轉化為:
void (*pf)(x &);
pf = bar;
考慮下面的類point3d:
class point3d
;
這個類的設計者應該提供乙個explicit copy constructor嗎?不需要,因為該類既沒有任何member(或base)class objects帶有copy constructor,也沒有任何的virtual base class或virtual function。所以,預設情況下,乙個point3d class object的「memberwise」初始化操作將導致「bitwise copy」(博主注:其實它們是一樣的)。這樣的效率很高,也很安全。因為資料成員是以數值儲存的。bitwise copy既不會導致memory leak,也不會產生address aliasing,因此,既快速,又安全。
那麼,該類的設計者到底應該提供乙個explicit copy constructor嗎?很明顯不要。但如果被問及是否預見class需要大量的memberwise初始化操作,例如以傳值的方式返回objects?如果回答是yes,那麼提供乙個copy constructor的explicit inline函式例項就非常合理——在你的編譯器提供nvr的前提下。
深度探索C 物件模型 2 3 程式轉化語意學
一 1 顯示的初始化操作 x x0 void foo bar 會被轉換成如下步驟 雙階段轉化 1 void foo bar 2view code 2 引數 形參 的初始化 1 void foo x x0 宣告2 3x xx 4foo xx 5 會被轉換成實際如下 6 voif foo x x0 78...
執行期語意學
物件的構造和析構 講解在以下幾種情況下 編譯器是如何安插構造和析構函式?1.全域性物件 2.區域性靜態物件 3.陣列物件 1 全域性物件 matrix g identity main c 保證了在main函式中第一次用到g str之前,將g str構造出來,在main 函式結束之前將g str毀掉。...
建構函式語意學
default建構函式操作 首先需要說明 帶來的第乙個問題,編譯器什麼時候合成預設建構函式 nontrivial 答案是編譯器需要的時候,而不是程式需要的時候。1 class foo class bar void foo bar 此時編譯器就會合成default 建構函式 類似 inline bar...