剖析C++多型:用C實現簡單多型
怎樣用C語言實現多型,首先想到的應該是去模擬C++的虛擬函式。
在C++中,每一個含有虛擬函式的類,都有一個虛擬函式表。對於類的每一個物件,都有一個指向虛擬函式表的指標。
用C語言模擬這個過程。先考慮最簡單的情況,只含有一個虛擬函式的類,並且只有建構函式,沒有虛解構函式。
假設這個類Base有一個int型別的成員變數val,虛擬函式run(int num)能夠輸出(val+num)的值。它的派生類Derived的結構與它類似,但是函式run(int num)輸出(val*num)的值。
C語言中並沒有類,所以我們用結構體來代替類,用含有指向類的指標的函式來表示類的成員函式。
程式碼如下:
#include <stdio.h>
#include <stdlib.h>
typedef int (*PFUNC)(void*, int); // 函式指標
/*這個宣告引入了 PFUNC 型別作為函式指標的同義字,該函式有個 void* 和 int 型別的引數以及一個 int 型別的返回值。 */
/*基類*/
typedef struct BASE {
PFUNC VIRTUAL;
int val;
} Base;
int BASE_RUN(void* self, int num) {
return ((Base*)self)->val + num;
}
Base* CONS_BASE(int val) {
Base* p = malloc(sizeof(Base));
p->VIRTUAL = BASE_RUN;
p->val = val;
return p;
}
/*派生類*/
typedef struct DERIVED {
PFUNC VIRTUAL;
int val;
} Derived;
int DERIVED_RUN(void* self, int num) {
return ((Derived*)self)->val * num;
}
Derived* CONS_DERIVED(int val) {
Derived* p = malloc(sizeof(Derived));
p->VIRTUAL = DERIVED_RUN;
p->val = val;
return p;
}
/*虛擬函式*/
int run(Base* p, int num) {
return p->VIRTUAL((void*)p, num);
}
int main()
{
Base* base = CONS_BASE(10);
Base* derived = (Base*)CONS_DERIVED(10);
int val_base = run(base, 10);
int val_derived = run(derived, 10);
printf("Base:%d\nDerived:%d\n", val_base, val_derived);
return 0;
}
函式CONS_BASE, CONS_DERIVED返回物件指標,可以看作類的建構函式。函式run可以看作是Base類的成員函式。
通過結構體的定義可以看出,結構體中有一個指向函式的指標VIRTUAL,他的作用類似於虛擬函式表,只不過因為表中只有一個函式,因此省略了表的結構。
在建構函式中,除了初始化val的值,還將函式BASE_RUN、DERIVED_RUN賦值給了函式指標VIRTUAL。當呼叫run時,通過self指標找到函式指標VIRTUAL。雖然self指標是指向Base的指標,但是由於Base與Derived的前4個位元組(32位)都是VIRTUAL指標,所以當基類的指標指向派生類時,VIRTUAL指標指向的也是派生類的成員函式DERIVED_RUN。這樣就實現了簡單的多型。
執行結果如下:
Base:20
Derived:100
成功。
複雜版本的思路:
首先結構體裡指向函式的指標要改成(void**)型別,指向一個虛擬函式表。而虛擬函式表要通過另外的一個函式初始化。各個函式在表中的位置要手動的指定,比如run函式在表中第一位,go函式在表中第二位。當呼叫函式時,首先找到虛擬函式表,再根據不同的編號去找到表中對應位的函式進行呼叫。
可以發現虛擬函式的呼叫比普通的函式呼叫多了一個查表的過程,降低了一點效率。
相關文章
- C++ 多型的實現及原理C++多型
- C++多型C++多型
- C++——多型C++多型
- c++實現多型的方法 虛表C++多型
- C/C++—— C++編譯器是如何實現多型C++編譯多型
- C++的多型C++多型
- C++多型性C++多型
- C/C++—— 對多型現象的理解C++多型
- C++編譯期多型與執行期多型C++編譯多型
- C++整理16_多型C++多型
- 虛擬函式表-C++多型的實現原理函式C++多型
- C++ 多型的實現原理與記憶體模型C++多型記憶體模型
- 多型 簡單講解多型
- C++(虛擬函式實現多型基本原理)C++函式多型
- 開心檔之C++ 多型C++多型
- C語言實現繼承多型C語言繼承多型
- 什麼是Java多型?如何實現Java多型?Java多型
- C++多工程式設計簡明教程(1)-C++的多工其實很簡單C++程式設計
- C++用多種方式實現Singleton單例模式C++單例模式
- C++多型之虛擬函式C++多型函式
- JAVA與C++的多型異同JavaC++多型
- C++和java多型的區別C++Java多型
- [c++] 繼承和多型整理二C++繼承多型
- C++虛擬函式與多型實戰 (轉)C++函式多型
- c++學習(1)--C++封裝、繼承、多型C++封裝繼承多型
- Go 如何實現多型Go多型
- C++ 簡單實現陣列類泛型程式設計示例C++陣列泛型程式設計
- 實現多型多對多 幾個注意點多型
- C++ 繼承、多型、虛擬函式C++繼承多型函式
- 關於c語言模擬c++的多型C語言C++多型
- go中如何實現多型Go多型
- C# 多型性C#多型
- C# 多型性C#多型
- c#多型性C#多型
- C++多型(上)——虛擬函式、虛表C++多型函式
- c#——泛型的多種應用C#泛型
- 再談多型--多型的應用舉例: (轉)多型
- C++智慧指標簡單剖析C++指標