Chapter 4.? The Semantics of Function: Function 語(yǔ)意學(xué)
4.1 Member 函數(shù)的各種調(diào)用方式
1. Nonstatic Member Function(非靜態(tài)成員函數(shù))
??? 要做如下的轉(zhuǎn)換:
??? (1) 改寫(xiě)函數(shù)的原形, 安插一個(gè)參數(shù)到member function中, 用于提供一個(gè)存取管道, 使class object 得以調(diào)用該函數(shù), 這個(gè)額外的指針?lè)Q之為: this指針.
??? 如:??
?Point3d::magnitude()? 會(huì)轉(zhuǎn)換為:? Point3d::magnitude(Point3d *const? this)
??? (2)? 對(duì)函數(shù)內(nèi)每一個(gè)針對(duì)nostatic data member的存取操作改經(jīng)由this指針來(lái)存取.
???? 如:
?????????? return sqrt(
??this->_x? *? this->_x? + this->y * this->_y? + this->_z * this->_z;
??? (3)? 將對(duì)member function 重寫(xiě)一個(gè)外部函數(shù), 對(duì)函數(shù)名稱進(jìn)行"mangling"處理, 使它生成一個(gè)獨(dú)一無(wú)二的名稱
???
2. Virtual Member Function(虛擬成員函數(shù))
???? 例如:
? ptr->normalize();
? 它將被轉(zhuǎn)化為如下的調(diào)用:
?( * ptr->vptr[ 1 ])( ptr );
?這里有幾點(diǎn)說(shuō)明:
?i.? vptr是由編譯器生成的指針,指向virtual table
?ii.? 1 這里是virtual table slot 的索引值,它關(guān)聯(lián)到nomalize這個(gè)函數(shù)
?iii.? 第二個(gè)ptr表示this指針
3. Static Member Function(靜態(tài)成員函數(shù))
???? 如果Point3d::normalize()是一個(gè)static member function的話,這兩個(gè)調(diào)用會(huì)轉(zhuǎn)化為一般的操作:
???? obj.normalize();
???? ptr->normalize();
???? 轉(zhuǎn)化為:
???? // obj.normalize();
???? normalize__7Point3dSFv();
???? // ptr->normalize();
???? normalize__7Point3dSfv();
4.2 Virtual Member Functions(虛擬成員函數(shù))
1. 單一繼承下的Virtual Functions
???? 一個(gè)多態(tài)的class object 身上增加兩個(gè)members:
?I.?? 一個(gè)字符串或數(shù)字,? 表示class的類型
?II.? 一個(gè)指針,指向某個(gè)表格,表格中帶有程序的virtual function的執(zhí)行時(shí)期地址
??? 對(duì)于一個(gè)active virtual function包括下面三個(gè)內(nèi)容:
??????? I.?? 這個(gè)class 所定義的函數(shù)實(shí)體, 它會(huì)改寫(xiě)一個(gè)可能存在的base class virtual function 函數(shù)實(shí)體.
?II.? 繼承自基類的實(shí)體, 這是在derived class 決定不改寫(xiě)virtual function 時(shí)才會(huì)出現(xiàn)的情況
?III. 一個(gè)pure_virtual_called()函數(shù)實(shí)體,它既可以扮演pur virtual function的空間保衛(wèi)者角色, 也可以當(dāng)做執(zhí)行期異常函數(shù).
2. 多重繼承下的Virtual Functions
??? 這種繼承涉及到要調(diào)整this指針,并且要求不止一個(gè)vtbl和vptr,同時(shí)要好幾個(gè)這種虛表和指針
3. 虛擬繼承下的Virtual Functions
4.3 函數(shù)的效能
4.4 指向Member Functions的指針(Pointer-to-Member Functions)
1. 指向一般成員函數(shù)的指針(Nostatic member and novirtual member function)
??? 取一個(gè)nostatic member function的地址,? 如果該函數(shù)是novirtual, 則得到的結(jié)果是它在內(nèi)存中真正的地址, 然而這個(gè)地址也不是完全的, 它也需要綁定到某個(gè)class object的地址上, 才能夠調(diào)用該函數(shù). 所有的nostatic member functions都要對(duì)象的地址(用this指出).
??? 例如:
???? double (Point::*pmf)();?// 定義一個(gè)成員函數(shù)指針
????? pfm = &Point::y;???// 初始化這個(gè)指針為
???? (ptr->*pfm)() ;???// 調(diào)用為,? 編譯器轉(zhuǎn)化為: (pfm)(ptr)
2. 支持"指向Virtual Member Functions"的指針
??? 對(duì)于virtual function, 其地址在編譯時(shí)期是未知的, 所能知道的僅是virtual function在相關(guān)的vitual table 中的索引值. 也就是說(shuō)對(duì)于一個(gè)virtual member function取其地址, 所能獲得的只是一個(gè)索引值.
??? 所以如果:
??? pmf = &Point::z();?// 獲得的是索引值,? 調(diào)用時(shí):
??? (ptr.->pmf)()???// 會(huì)轉(zhuǎn)化為: (* ptr->vptr[(int)pfm] (ptr)
3. 在多重繼承下,指向Member Functions的指針
???? 比較復(fù)雜,? 定義了一個(gè)結(jié)構(gòu)支持這們的操作
4. 指向 Member Functions 指針的效率
4.4 Inline Functions
1. inline functions的生成條件
2. 對(duì)形式參數(shù)的處理(Formal Arguments)
例如:
?1?inline?int?min(?int?i,?int?j?)?
?2??{?
?3?????return?i?<?j???i?:?j;?
?4??}?
?5??and?the?following?three?invocations?of?the?inline?function:
?6?
?7??inline?int?bar()?
?8??{?
?9?????int?minval;?
10?????int?val1?=?1024;?
11?????int?val2?=?2048;?
12?
13??/*(1)*/minval?=?min(?val1,?val2?);?
14??/*(2)*/minval?=?min(?1024,?2048?);?
15??/*(3)*/minval?=?min(?foo(),?bar()+1?);?
16?
17?????return?minval;?
18??}?
?
用下面的方式進(jìn)行處理:
?? (1)? 直接的參數(shù)替換
?//(1)???? simple argument substitution
?minval = val1 < val2 ? val1 : val2;
?? (2) 如果實(shí)際參數(shù)是一個(gè)常量表達(dá)式(const expression),? 我們就可以在替換前完成對(duì)它的求值操作.
?//(2)? constant folding following substitution
?minval = 1024;
??
?? (3) 帶有副作用的實(shí)際參數(shù), 引入臨時(shí)性的對(duì)象
?//(3)???? side-effects and introduction of temporary
?int t1;
?int t2;
?minval =? ( t1 = foo() ), ( t2 = bar() + 1 ),? t1 < t2 ? t1 : t2;
3. 對(duì)inline函數(shù)帶有局部變量的處理(Local Variables)
??? 如:
?inline int min( int i, int j )
?{
??int minval = i < j ? i : j;
??return minval;
?}
??? 對(duì)于如下的調(diào)用:
??? {
??? int local_var;
??? int minval;
??? // ...
??? minval = min( val1, val2 );
???? }
??? 轉(zhuǎn)換可能的結(jié)果是:
1?????{?
2?????int?local_var;?
3?????int?minval;?
4?????//?mangled?inline?local?variable?
5?????int?__min_lv_minval;?
6?
7?????minval?=??(?__min_lv_minval?=??val1?<?val2???val1?:?val2?),??__min_lv_minval;?
8??????}
?