C語言 用C語言實現C 繼承與多型

2021-10-20 19:16:34 字數 4336 閱讀 9781

繼承就是當建立乙個類時,不需要重新編寫新的資料成員和成員函式,只需指定新建的類繼承了乙個已有的類的成員即可。這個已有的類稱為基類,新建的類稱為派生類

舉個例子:人是動物,人具有動物的行為和屬性,但人也有動物所不具備的行為和屬性。

動物行為

屬性會動體力人

行為屬性

會動體力

會學習智力

本實現使用了組合的方式,即把基類作為派生類的成員變數之一。

但是一定要將基類放在派生類首部,這要基類和派生類的記憶體首部分布才一致。

/* 基類 */

typedef struct _animal_t animal_t; /* 動物類 */

struct _animal_t

;

/* 派生類 */

typedef struct _human_t human_t; /* 人類 */

在派生類中的建構函式需要呼叫基類的建構函式用於初始化,然後再將建構函式建立的基類物件拷貝到派生類中。

但由於是淺拷貝,即只拷貝了位址,沒有拷貝位址的內容。所以要在派生類中加入基類指標成員變數,用於在析構函式釋放記憶體。

typedef struct _human_t human_t;/* 人類 */

struct _human_t

;human_t* human_born(void); /* 建構函式 */

void human_die(human_t* this); /* 析構函式 */

human_t* human_born(void)

void human_die(human_t* this)

typedef struct _animal_t animal_t;	/* 動物類 */

struct _animal_t

;void act(void* this); /* 動 */

typedef struct _human_t human_t;/* 人類 */

struct _human_t

;void learn(void* this);

void act(void* this)

else

}

void learn(void* this)

else

}

在上個例子中,人和動物都有會動的屬性,但人的動作和動物的動作從表現上會有所不同。而多型就可以實現在同乙個函式中,根據物件型別的不同,函式實現方式也不同。

c語言多型的實現,需要用到函式指標。函式名實際上是該函式**儲存空間的首位址,這個位址可以通過函式指標來存放。通過改變函式指標儲存的位址就可以實現多型。

typedef struct _animal_t animal_t;

typedef void (*animal_act_t)(animal_t*); /* 函式指標型別 */

typedef struct _animal_vtable_t /* 虛函式表 */

animal_vtable_t;

struct _animal_t

;animal_t* animal_born(void); /* 建構函式 */

void act(void* this); /* 函式介面 */

void animal_die(animal_t* this); /* 析構函式 */

static void animal_act(animal_t* this);

/* 動物類的虛函式表 */

static animal_vtable_t __g_animal_vtable =

;animal_t* animal_born(void)

void act(void* this)

/* 實現函式 */

static void animal_act(animal_t* this)

else }

void animal_die(animal_t* this)

該**將結合上述繼承和多型的方法實現對基類函式進行重寫:

/* animal.h */

#ifndef _animal_h_

#define _animal_h_

#include #include #include typedef struct _animal_t animal_t;

typedef void (*animal_act_t)(animal_t*);

typedef struct _animal_vtable_t

animal_vtable_t;

struct _animal_t

;animal_t* animal_born(void);

void act(void* this);

void animal_die(animal_t* this);

#endif /* _animal_h_ */

/* animal.c */

#include "animal.h"

static void animal_act(animal_t* this);

static animal_vtable_t __g_animal_vtable =

;animal_t* animal_born(void)

void act(void* this)

printf("can't act\n");

}static void animal_act(animal_t* this)

else }

void animal_die(animal_t* this)

/* human.h */

#ifndef _human_h_

#define _human_h_

#include "animal.h"

typedef struct _human_t human_t;

typedef void (*human_learn_t)(human_t*);

typedef struct _human_vtable_t

human_vtable_t;

struct _human_t

;human_t* human_born(void);

void learn(void* this);

void human_die(human_t* this);

#endif /* _human_h_ */

/* human.c */

#include "human.h"

static void human_act(human_t* this);

static void human_learn(human_t* this);

static animal_vtable_t __g_animal_vtable;

static human_vtable_t __g_human_vtable =

;human_t* human_born(void)

void learn(void* this)

printf("can't learn\n");

}static void human_act(human_t* this)

else }

static void human_learn(human_t* this)

void human_die(human_t* this)

/* main.c */

#include "animal.h"

#include "human.h"

int main()

結果如下:

C語言實現繼承與多型

在前面部落格已經詳細講過c 中繼承與多型的概念,在這裡則只使用c語言的語法來實現繼承與多型。繼承 即派生類中擁有基類的成員變數和成員函式,所以c語言實現如下 include typedef void func void void funb typedef struct b b typedef str...

C語言實現繼承和多型

一 面向過程程式設計與物件導向程式設計的區別 眾所周知,c語言是一種典型的面向過程程式語言,而c 確實在它的基礎上改進的一款物件導向程式設計語言,那麼,面向過程與物件導向到底有什麼樣的區別呢?從設計方法角度看 面向過程程式設計方法採用函式 或過程 來描述對資料的操作,但又將函式與其操作的資料分離開來...

C語言實現封裝 繼承 多型

c語言中雖然沒有類,但有struct和指標。我們可以在乙個struct中存入資料和函式指標,以此來模擬類行為。typedef struct parent parent typedef struct child child include include 模擬乙個類a typedef struct a...