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

純 C 語言實現面向物件介面程式設計

     編輯:關於C語言

設計理念

C 語言雖無原生類別,但可透過結構體包含函式指標模擬介面、繼承與多型。核心技巧:

  • 基底結構體內嵌函式指標表(虛函式表)
  • 子類別結構體首欄位嵌入基底結構體(組合模擬繼承)
  • 建構函式動態分配記憶體並綁定虛函式

檔案結構

project/
├── Shape.h / Shape.c      // 基底介面:Shape
├── Triangle.h / Triangle.c // 子類:三角形
├── Rectangle.h / Rectangle.c // 子類:矩形
└── Main.c                 // 測試程式

核心代碼實現

Shape.h - 基底介面定義


#ifndef SHAPE_H_
#define SHAPE_H_

#include <stdlib.h>

// 前向宣告
typedef struct Shape Shape;
typedef Shape* p_shape;

// 虛函式表
typedef struct {
    int (*getEdge)(p_shape);
    double (*calcArea)(p_shape);
    void (*_Shape)(p_shape); // 解構子
} ShapeVTable;

// Shape 結構體
struct Shape {
    ShapeVTable *vptr; // 指向虛函式表
    int edge;
};

// 介面函式宣告
p_shape Shape(int edge);
void _Shape(p_shape);

#endif

Shape.c - 基底實現


#include "Shape.h"

static int getEdge(p_shape this) { return this->edge; }
static double calcArea(p_shape this) { return 0.0; } // 純虛函式預設
static void _Shape(p_shape this) { free(this); }

static ShapeVTable vtable = {
    .getEdge = getEdge,
    .calcArea = calcArea,
    ._Shape = _Shape
};

p_shape Shape(int edge) {
    p_shape s = (p_shape)malloc(sizeof(Shape));
    if (s) {
        s->vptr = &vtable;
        s->edge = edge;
    }
    return s;
}

void _Shape(p_shape this) {
    if (this) this->vptr->_Shape(this);
}

Triangle.h / Triangle.c - 三角形實現


// Triangle.h
#ifndef TRIANGLE_H_
#define TRIANGLE_H_
#include "Shape.h"

typedef struct Triangle Triangle;
typedef Triangle* p_triangle;

struct Triangle {
    Shape super; // 繼承:首欄位為基底
    double bottom;
    double height;
};

p_triangle Triangle(double bottom, double height);
void _Triangle(p_triangle);
#endif

// Triangle.c
#include "Triangle.h"

static int getEdge(p_shape this) {
    p_triangle t = (p_triangle)this;
    return 3;
}
static double calcArea(p_shape this) {
    p_triangle t = (p_triangle)this;
    return t->bottom * t->height / 2.0;
}
static void _Triangle(p_triangle this) {
    if (this) this->super.vptr->_Shape((p_shape)this);
}

p_triangle Triangle(double bottom, double height) {
    p_triangle t = (p_triangle)malloc(sizeof(Triangle));
    if (t) {
        t->super = *Shape(0); // 初始化基底部分
        t->super.vptr->getEdge = getEdge;
        t->super.vptr->calcArea = calcArea;
        t->super.vptr->_Shape = (void(*)(p_shape))_Triangle;
        t->bottom = bottom;
        t->height = height;
    }
    return t;
}

Rectangle.h / Rectangle.c - 矩形實現(類似 Triangle)


// 結構體
struct Rectangle {
    Shape super;
    double width;
    double height;
};
// 虛函式實現 getEdge 回傳 4,calcArea 回傳 width*height

Main.c - 多型測試


#include <stdio.h>
#include "Triangle.h"
#include "Rectangle.h"

int main() {
    p_triangle tri = Triangle(3.0, 4.0);
    p_rectangle rect = Rectangle(5.0, 6.0);

    p_shape shapes[2] = { (p_shape)tri, (p_shape)rect };

    for (int i = 0; i < 2; ++i) {
        printf("Shape %d: edges=%d, area=%.2f\n",
               i+1,
               shapes[i]->vptr->getEdge(shapes[i]),
               shapes[i]->vptr->calcArea(shapes[i]));
        shapes[i]->vptr->_Shape(shapes[i]); // 多型解構
    }
    return 0;
}

編譯與執行結果


$ gcc -std=c99 Shape.c Triangle.c Rectangle.c Main.c -o oop_demo
$ ./oop_demo
Shape 1: edges=3, area=6.00
Shape 2: edges=4, area=30.00

關鍵技術總結

  1. 虛函式表:每個類別擁有靜態虛函式表,實例指向該表實現動態分派。
  2. 結構體組合:子類別首欄位嵌入基底結構體,保證記憶體佈局相容,可安全轉型。
  3. 建構/解構函式:負責記憶體分配、虛函式綁定與釋放,模擬 C++ RAII。
  4. 單一繼承:此模式支援單一繼承;多重繼承需更複雜的偏移量調整。

應用場景

  • 嵌入式系統無 C++ 編譯器時
  • 需精確控制記憶體佈局的系統程式
  • 跨語言介面(如 C 呼叫 C++ 物件)的橋接層
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved