在c++中,物件導向是通過虛函式來實現的,僅有虛函式,當然只是乙個物件導向的皮毛,因為實際上真正的物件導向概念訊息和訊息響應。先撇開目前市面上物件導向中關於封裝變化,依賴倒轉等一些概念性和理論性的東西。我們在這邊,僅考慮c++中虛函式在c中的模擬實現,以便於更好的理解虛函式。
假定我們現在有乙個函式的原形如下
int print_char(int c);
在c語言中,可以通過typedef方式定義乙個函式的原形指標:
typedef int (*lpfnprint)(int c);
函式原形的指標形式定義了更一般的函式方式。在c++中class或者struct是包含資料和操作(函式)的集合,class只是預設是私有的struct的實現。在c語言中,只有struct型別,因此不存在public和private的語法說明。在c語言中,struct是乙個資料型別的集合,如果我們把函式指標也看作是乙個資料(本來這個就是乙個資料,指向某個函式的資料,同時也是乙個操作),那麼在c語言中的struct也就可以包含資料和操作。
struct baseclass
實現print函式
int print_char(int c)
int print_int(int c)
於是,我們可以定義乙個結構體的變數
baseclass b;
b.lpfn_print = print_char;
此時,我們就可以用b.lpfn_print(97)輸出字元a了。
當我們修改列印函式為
b.lpfn_print = print_int
再次呼叫b.lpfn_print(97);就可以輸出整數97。
這個是在執行時進行函式的繫結,與c++中編譯器中的虛函式編譯時繫結還是有一些差別的。
上面的實現,已經有些虛函式的概念,但與現在的c++中的虛函式還是有乙個差別。要想得到類似c++的虛函式,就得了解c++中對於虛函式的實現,一般而言,c++的虛函式是通過虛函式表實現的,虛函式表是乙個陣列,索引代表乙個函式指標,實現了具體函式的呼叫。因此,我們可以定義乙個只包含函式指標的結構體型別來表示虛函式,我們命之為virtualtable。
struct virtualtable
;
然後我們再定義下面的結構體
struct base
;struct device
;上面的device和base具有相同的結構體內存型別,只是包含了不同的名字,因此我們可以在main函式進行如下的呼叫:
int main()
; // 本來編譯做的事情,現在由我們手工做了。
struct device d = ;
// 定義結構體指標
struct base *p = null;
p = &b;
p->v.print_func(97);
p = &d; // 和c++中從基類中派生後的函式類似
p->v.print_func(97);
return 0;
}
p->v.print_func,與c++中對於虛函式的呼叫就非常類似了。
結構體與指標
struct s options opt 此時結構體內的資料都是乙個隨機數 struct s options opts struct s options malloc sizeof struct s options 8 此時各元素為預設初始化值,例如int就是0 一 結構體的定義方法 1 直接定義 ...
指標與結構體
宣告 c c 內容來自西交公開課,之後不再宣告,僅作為筆記 thx.指標與結構體 結構體變數的指標 位址 結構體變數名 使用指標處理結構體變數步驟 1.定義指向結構體變數的指標 結構體型別 指標變數名 2.給指標變數提供初值 格式1 指標變數 成員名 格式2 指標變數 成員名 其中 稱為結構指向運算...
指標與結構體
指標是乙個變數,它儲存了另乙個變數的位址。指標主要的功能有兩個 避免副本和共享資料。作用是什麼?參考 1 定義指標變數的一般形式為 基型別 指標變數名,如 int pointer 1 float pointer 2 char pointer 3等,在定義指標變數時必須指定其型別。2 兩個相關的運算子...