深度探索C 物件模型 Function語意學

2021-07-04 07:51:51 字數 4210 閱讀 3030

-nonstatic member function設計準則:與一般非成員函式(nonmember function)有相同的執行效率。因此,實際上編譯器內部將nonstatic member 函式實體轉化為對等的nonmember 函式實體。

-轉換過程:

1. 新增額外this指標,提供資料訪問管道

2. 修改函式體內成員資料訪問方式,改為使用this指標訪問

3. 對函式名字重新「mangling」修飾處理

class a

int a::func() //nonstatic member function

int a::func(a *const

this) //1.新增額外引數this指標

int a::func(a *const

this) //2.改為由this指標訪問成員資料

extern

int func_1afv(a *const

this) //3.對函式名進行「mangling」修飾

obj.func() ---> func_1afv(&obj)

member function過載化,以提供獨一無二名稱,採用該手法。 函式

名稱+類

名稱+參

數數目+

引數型別

//可能的修飾方法:

int point::foo(float x) ---> int foo_5pointff(float x)

int point::foo(void) ---> int foo_5pointfv()

-靜態成員函式沒有this指標:

1. 不用直接訪問class中nonstatic members

2. 不能被宣告為const, volatile 或者virtual

3. 不需要有class object才能被呼叫

-static member function會被編譯器轉化為nonmember形式,實際上該類函式產不多等同於nonmember function。

static int a::func()   //靜態成員函式

//各種方式呼叫靜態函式,均轉換成通過類作用於直接呼叫

ptr->func()/obj.func()/a::func() --> a::func()

//函式mangling修飾

a::func() ---> func_1asfv() //sfv表示靜態成員函式,引數void

//1是virtual table slot索引,關聯到func函式

ptr->func() -->(*ptr->vptr[1])(ptr)

//明確的呼叫可以抑制虛擬機制

a::func()

// 通過該obj呼叫不支援多型

obj.func() ---> func_1afv(&obj)

-通過class object呼叫virtual function的操作會被編譯器轉換為一般的nonmember member function,不呈現多型。

下面將虛函式的呼叫。

c++多型:以乙個public base class的指標,定址出乙個derived class object。

//呼叫虛函式,如何在執行期確定func()實體

ptr->func()

class point 

virtual

float y() const //slot 3

virtual

float z() const //slot 4

protected:

point (float x = 0.0);

float _x;

}class point2d:public point //函式覆蓋 slot 3

protected:

float _y;

}class point3d:public point2d //函式覆蓋 slot 4

protected:

float _z;

}//一般來說我們事先並不知道ptr所指物件真正型別

//所以不知道哪個mult實體會被呼叫,但mult()固定在slot 2中是確定的

ptr->mult()

//因此編譯器如下轉換

//執行期唯一需要做的就是確定哪乙個slot 2的實體

//編譯時期就將指標轉移至第二個base class起始位址

base2 *pbase2 = new derived;

//執行時需要調整pbase2至derived起始位址

delete pbase2; //該行**無法在編譯時知道pbase2的真實物件,執行時才知道

-多重繼承結構如下:derived會有兩個vtbl被編譯器產生:(1)主體實體,與base1(最左端base class)共用 (2)次要實體,與base2有關

-三種需要調整指標的情況

1 通過指向base2的指標,呼叫derived class virtual function。

//編譯時期就將指標轉移至第二個base class起始位址

base2 *pbase2 = new derived;

//執行時需要調整pbase2至derived起始位址

delete pbase2;

2 通過指向derived class的指標,呼叫第二個base claass中的乙個繼承而來的virtual function。

//編譯時期就將指標轉移至第二個base class起始位址

derived *pder =

new derived;

//執行時需要調整pder以指向base2 subobject

pder->mumble; //呼叫base2::mumble()

3 三個clone函式實體返回值型別不同

//編譯時期就將指標轉移至第二個base class起始位址

base2 *pbase2 = new derived;

//呼叫derived* derived::clone()

//需要將pbase2指標調整至derived class起始處

//返回值時又需要重新調整至base2 subobject

base1 *pbase2_new = pbase2->clone;

-得到真實位址,但它需要繫結與某個class object上,才能通過它呼叫。

double (point::*coord) = &point::x;

//nonvirtual function

//呼叫函式

(obj.*coord) ()

//被編譯器轉化

(coord)(&obj) //&obj為this指標

-static member function函式位址為普通函式指標,因為沒有this指標。

class point

float (point::*pmf) = point::z; //= 2

point *ptr = new point2d;

ptr->*pmf;

//被編譯器轉化為

(*ptr->vptr[(int)pmf](ptr));

問題:如何區別member function指標指向位址還是virtual table索引?

方法:修改member function指標mptr結構體,mptr->index正負判別。

struct __mptr 

}

深度探索C 物件模型

傳世經典書叢 深度探索c 物件模型 美 stanley b.lippman 斯坦利 b.李普曼 著 侯捷 譯 isbn978 7 121 14952 8 2012年1月出版 定價 69.00元 16開 356頁 宣傳語 如果你是一位c 程式設計師,渴望對於底層知識獲得乙個完整的了解,那麼本書正適合你...

深度探索C 物件模型

傳世經典書叢 深度探索c 物件模型 美 stanley b.lippman 斯坦利 b.李普曼 著 侯捷譯 isbn978 7 121 14952 8 2012年1月出版 定價 69.00元 16開 356頁 宣傳語 如果你是一位c 程式設計師,渴望對於底層知識獲得乙個完整的了解,那麼本書正適合你 ...

深度探索C 物件模型

深度探索c 物件模型 本書目錄結構如下 第1章 關於物件 object lessons 加上封裝後的布局成本 layout costs for adding encapsulation 1.1 c 模式模式 the c object model 簡單物件模型 a object model 驅動物件模...