首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C 語言實現面向對象:手寫繼承與多態(虛表機制)

     編輯:關於C

核心思想

C 無原生類,但可用 結構體 + 函數指針 模擬封裝、繼承、多態。關鍵是構建 虛函數表,並在基類/派生類對象間建立雙向引用。

基類 Person 設計

// Person.h
typedef struct _Person Person;

// 虛函數指針類型
typedef void (*DisplayFn)(Person*);
typedef void (*WriteFn)(Person*, const char*);
typedef void (*DeleteFn)(Person*);

struct _Person {
    void *derivedObj;      // 指向派生對象 (多態關鍵)
    char *firstName;
    char *lastName;
    DisplayFn display;     // 虛表槽位
    WriteFn writeToFile;
    DeleteFn delete;
};

// 構造/析構
Person* new_Person(const char*, const char*);
void delete_Person(Person*);

// 虛函數實現
void Person_Display(Person*);
void Person_WriteToFile(Person*, const char*);

構造函數初始化虛表

// Person.c
Person* new_Person(const char *fn, const char *ln) {
    Person *p = malloc(sizeof(Person));
    p->derivedObj = p; // 基類指向自己
    p->firstName = strdup(fn);
    p->lastName = strdup(ln);
    // 綁定基類虛函數
    p->display = Person_Display;
    p->writeToFile = Person_WriteToFile;
    p->delete = delete_Person;
    return p;
}

void delete_Person(Person *p) {
    free(p->firstName); free(p->lastName); free(p);
}

派生類 Employee 繼承與覆寫

// Employee.h
#include "Person.h"
typedef struct _Employee Employee;

struct _Employee {
    Person *baseObj;       // 指向基類對象
    char *department;
    char *company;
    int salary;
};

Person* new_Employee(const char*, const char*, const char*, const char*, int);
void delete_Employee(Person*); // 參數為基類指針,實現多態刪除
void Employee_Display(Person*);
void Employee_WriteToFile(Person*, const char*);

派生構造函數:劫持基類虛表

// Employee.c
Person* new_Employee(const char *fn, const char *ln,
                     const char *dept, const char *comp, int sal) {
    Person *base = new_Person(fn, ln); // 調用基類構造
    Employee *e = malloc(sizeof(Employee));
    e->baseObj = base;
    e->department = strdup(dept);
    e->company = strdup(comp);
    e->salary = sal;

    // 關鍵:修改基類虛表指向派生實現
    base->derivedObj = e;
    base->display = Employee_Display;
    base->writeToFile = Employee_WriteToFile;
    base->delete = delete_Employee; // 析構也多態化
    return base; // 返回基類指針,支持多態調用
}

void delete_Employee(Person *p) {
    Employee *e = (Employee*)p->derivedObj;
    free(e->department); free(e->company); free(e);
    delete_Person(p); // 鏈式調用基類析構
}

多態調用演示

Person *p1 = new_Person("Anjali", "Jaiswal");
Person *p2 = new_Employee("Gauri", "Jaiswal", "HR", "TCS", 40000);

p1->display(p1);           // 調用 Person_Display
p2->display(p2);           // 調用 Employee_Display (多態)
p2->delete(p2);            // 正確釋放 Employee + Person 內存

機制總結

機制C++C 手寫模擬
虛表編譯器自動生成結構體內函數指針數組
this 指針隱式傳遞顯式作為第一參數傳遞
繼承內存佈局拼接基類含派生指針,派生含基類指針
多態調用vptr→vtable→函數基類虛表槽位被派生構造函數覆寫
析構多態virtual destructor基類 delete 槽位指向派生析構函數

工程價值

理解此模型有助於:

  • 深入掌握 C++ 物件模型底層實現;
  • 在嵌入式 C 專案中實現插件架構、驅動抽象層;
  • 面試時手寫多態機制展示底層功力。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved