C语言模拟面向对象编程方法之多态

目录

C++ 中多态

多态的介绍:

多态是面向对象编程的三大特性之一,它允许不同类的对象对同一消息做出不同的响应。多态性意味着"多种形态",即同一个接口可以有不同的实现方式

多态的类型:

  • 编译时多态(静态多态):通过函数重载和运算符重载实现
  • 运行时多态(动态多态):通过虚函数和继承关系实现

多态的意义:

  • 提高代码灵活性:相同的接口可以有不同的行为
  • 增强可扩展性:新增派生类不影响现有代码
  • 实现接口统一:不同对象可以通过统一接口操作

多态的用途:

  • 实现接口统一:为不同对象提供统一的操作接口
  • 增强代码可维护性:减少条件判断语句,提高代码可读性
  • 支持动态绑定:运行时根据对象类型调用相应方法
  • 实现设计模式:如工厂模式、策略模式等的基础

多态使用实例

cpp 复制代码
#include <iostream>
#include <vector>
#include <memory>

// 抽象基类:图形
class Shape {
protected:
    std::string name;
    
public:
    Shape(const std::string& n) : name(n) {}
    virtual ~Shape() = default;
    
    // 纯虚函数 - 接口定义
    virtual double calculateArea() const = 0;
    virtual double calculatePerimeter() const = 0;
    virtual void displayInfo() const {
        std::cout << "Shape: " << name << std::endl;
    }
    
    std::string getName() const { return name; }
};

// 具体派生类:圆形
class Circle : public Shape {
private:
    double radius;
    
public:
    Circle(double r) : Shape("Circle"), radius(r) {}
    
    double calculateArea() const override {
        return 3.14159 * radius * radius;
    }
    
    double calculatePerimeter() const override {
        return 2 * 3.14159 * radius;
    }
    
    void displayInfo() const override {
        Shape::displayInfo();
        std::cout << "Radius: " << radius 
                  << ", Area: " << calculateArea()
                  << ", Perimeter: " << calculatePerimeter() << std::endl;
    }
};

// 具体派生类:矩形
class Rectangle : public Shape {
private:
    double width;
    double height;
    
public:
    Rectangle(double w, double h) : Shape("Rectangle"), width(w), height(h) {}
    
    double calculateArea() const override {
        return width * height;
    }
    
    double calculatePerimeter() const override {
        return 2 * (width + height);
    }
    
    void displayInfo() const override {
        Shape::displayInfo();
        std::cout << "Width: " << width << ", Height: " << height
                  << ", Area: " << calculateArea()
                  << ", Perimeter: " << calculatePerimeter() << std::endl;
    }
};

// 具体派生类:三角形
class Triangle : public Shape {
private:
    double side1, side2, side3;
    
public:
    Triangle(double s1, double s2, double s3) 
        : Shape("Triangle"), side1(s1), side2(s2), side3(s3) {}
    
    double calculateArea() const override {
        // 使用海伦公式计算面积
        double s = (side1 + side2 + side3) / 2;
        return sqrt(s * (s - side1) * (s - side2) * (s - side3));
    }
    
    double calculatePerimeter() const override {
        return side1 + side2 + side3;
    }
    
    void displayInfo() const override {
        Shape::displayInfo();
        std::cout << "Sides: " << side1 << ", " << side2 << ", " << side3
                  << ", Area: " << calculateArea()
                  << ", Perimeter: " << calculatePerimeter() << std::endl;
    }
};

// 使用多态
void demonstratePolymorphism() {
    std::vector<std::unique_ptr<Shape>> shapes;
    
    // 创建不同类型的图形对象
    shapes.push_back(std::make_unique<Circle>(5.0));
    shapes.push_back(std::make_unique<Rectangle>(4.0, 6.0));
    shapes.push_back(std::make_unique<Triangle>(3.0, 4.0, 5.0));
    
    // 统一接口操作不同类型的对象
    std::cout << "=== Polymorphism Demo ===" << std::endl;
    for (const auto& shape : shapes) {
        shape->displayInfo();  // 动态绑定,调用各自的具体实现
        std::cout << "---" << std::endl;
    }
    
    // 计算总面积 - 多态的威力
    double totalArea = 0.0;
    for (const auto& shape : shapes) {
        totalArea += shape->calculateArea();  // 每个对象调用自己的面积计算方法
    }
    std::cout << "Total Area: " << totalArea << std::endl;
}

int main() {
    demonstratePolymorphism();
    return 0;
}

C语言模拟面向对象多态

C语言没有原生的多态支持,但可以通过函数指针和结构体来模拟运行时多态。核心思想是在基类结构体中定义函数指针表(虚函数表),派生类通过提供不同的函数实现来覆盖这些函数指针

模拟过程

c 复制代码
// shape.h - 抽象基类接口
#ifndef SHAPE_H
#define SHAPE_H

typedef struct Shape Shape;

// 形状操作接口 - 模拟抽象基类的纯虚函数
typedef double (*CalculateAreaFunc)(const Shape* shape);
typedef double (*CalculatePerimeterFunc)(const Shape* shape);
typedef void (*DisplayInfoFunc)(const Shape* shape);

// 形状虚函数表
typedef struct {
    CalculateAreaFunc calculate_area;
    CalculatePerimeterFunc calculate_perimeter;
    DisplayInfoFunc display_info;
} ShapeVTable;

// 形状基类结构体
struct Shape {
    const char* name;
    const ShapeVTable* vtable;  // 虚函数表指针
};

// 公共接口函数
double shape_calculate_area(const Shape* shape);
double shape_calculate_perimeter(const Shape* shape);
void shape_display_info(const Shape* shape);
const char* shape_get_name(const Shape* shape);

#endif // SHAPE_H
c 复制代码
// shape.c - 基类实现
#include <stdio.h>
#include "shape.h"

// 基类公共接口实现
double shape_calculate_area(const Shape* shape) {
    if (shape && shape->vtable && shape->vtable->calculate_area) {
        return shape->vtable->calculate_area(shape);
    }
    return 0.0;
}

double shape_calculate_perimeter(const Shape* shape) {
    if (shape && shape->vtable && shape->vtable->calculate_perimeter) {
        return shape->vtable->calculate_perimeter(shape);
    }
    return 0.0;
}

void shape_display_info(const Shape* shape) {
    if (shape && shape->vtable && shape->vtable->display_info) {
        shape->vtable->display_info(shape);
    }
}

const char* shape_get_name(const Shape* shape) {
    return shape ? shape->name : NULL;
}
c 复制代码
// circle.h - 圆形派生类
#ifndef CIRCLE_H
#define CIRCLE_H

#include "shape.h"

typedef struct Circle Circle;

// 创建和销毁函数
Circle* circle_create(double radius);
void circle_destroy(Circle* circle);

// 获取特定属性
double circle_get_radius(const Circle* circle);

#endif // CIRCLE_H
c 复制代码
// circle.c - 圆形实现
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "circle.h"

// 圆形结构体
struct Circle {
    Shape base;  // 继承形状基类
    double radius;
};

// 圆形的方法实现
static double circle_calculate_area(const Shape* shape) {
    const Circle* circle = (const Circle*)shape;
    return 3.14159 * circle->radius * circle->radius;
}

static double circle_calculate_perimeter(const Shape* shape) {
    const Circle* circle = (const Circle*)shape;
    return 2 * 3.14159 * circle->radius;
}

static void circle_display_info(const Shape* shape) {
    const Circle* circle = (const Circle*)shape;
    printf("Shape: %s\n", circle->base.name);
    printf("Radius: %.2f, Area: %.2f, Perimeter: %.2f\n",
           circle->radius,
           circle_calculate_area(shape),
           circle_calculate_perimeter(shape));
}

// 圆形虚函数表
static const ShapeVTable circle_vtable = {
    .calculate_area = circle_calculate_area,
    .calculate_perimeter = circle_calculate_perimeter,
    .display_info = circle_display_info
};

// 圆形构造函数
Circle* circle_create(double radius) {
    Circle* circle = (Circle*)malloc(sizeof(Circle));
    if (!circle) return NULL;
    
    circle->base.name = "Circle";
    circle->base.vtable = &circle_vtable;
    circle->radius = radius;
    
    return circle;
}

void circle_destroy(Circle* circle) {
    free(circle);
}

double circle_get_radius(const Circle* circle) {
    return circle ? circle->radius : 0.0;
}
c 复制代码
// rectangle.h - 矩形派生类
#ifndef RECTANGLE_H
#define RECTANGLE_H

#include "shape.h"

typedef struct Rectangle Rectangle;

Rectangle* rectangle_create(double width, double height);
void rectangle_destroy(Rectangle* rectangle);

double rectangle_get_width(const Rectangle* rectangle);
double rectangle_get_height(const Rectangle* rectangle);

#endif // RECTANGLE_H
c 复制代码
// rectangle.c - 矩形实现
#include <stdio.h>
#include <stdlib.h>
#include "rectangle.h"

struct Rectangle {
    Shape base;  // 继承形状基类
    double width;
    double height;
};

static double rectangle_calculate_area(const Shape* shape) {
    const Rectangle* rect = (const Rectangle*)shape;
    return rect->width * rect->height;
}

static double rectangle_calculate_perimeter(const Shape* shape) {
    const Rectangle* rect = (const Rectangle*)shape;
    return 2 * (rect->width + rect->height);
}

static void rectangle_display_info(const Shape* shape) {
    const Rectangle* rect = (const Rectangle*)shape;
    printf("Shape: %s\n", rect->base.name);
    printf("Width: %.2f, Height: %.2f, Area: %.2f, Perimeter: %.2f\n",
           rect->width, rect->height,
           rectangle_calculate_area(shape),
           rectangle_calculate_perimeter(shape));
}

static const ShapeVTable rectangle_vtable = {
    .calculate_area = rectangle_calculate_area,
    .calculate_perimeter = rectangle_calculate_perimeter,
    .display_info = rectangle_display_info
};

Rectangle* rectangle_create(double width, double height) {
    Rectangle* rect = (Rectangle*)malloc(sizeof(Rectangle));
    if (!rect) return NULL;
    
    rect->base.name = "Rectangle";
    rect->base.vtable = &rectangle_vtable;
    rect->width = width;
    rect->height = height;
    
    return rect;
}

void rectangle_destroy(Rectangle* rectangle) {
    free(rectangle);
}

double rectangle_get_width(const Rectangle* rectangle) {
    return rectangle ? rectangle->width : 0.0;
}

double rectangle_get_height(const Rectangle* rectangle) {
    return rectangle ? rectangle->height : 0.0;
}
c 复制代码
// triangle.h - 三角形派生类
#ifndef TRIANGLE_H
#define TRIANGLE_H

#include "shape.h"

typedef struct Triangle Triangle;

Triangle* triangle_create(double side1, double side2, double side3);
void triangle_destroy(Triangle* triangle);

double triangle_get_side1(const Triangle* triangle);
double triangle_get_side2(const Triangle* triangle);
double triangle_get_side3(const Triangle* triangle);

#endif // TRIANGLE_H
c 复制代码
// triangle.c - 三角形实现
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "triangle.h"

struct Triangle {
    Shape base;  // 继承形状基类
    double side1, side2, side3;
};

static double triangle_calculate_area(const Shape* shape) {
    const Triangle* triangle = (const Triangle*)shape;
    double s = (triangle->side1 + triangle->side2 + triangle->side3) / 2;
    return sqrt(s * (s - triangle->side1) * 
                (s - triangle->side2) * (s - triangle->side3));
}

static double triangle_calculate_perimeter(const Shape* shape) {
    const Triangle* triangle = (const Triangle*)shape;
    return triangle->side1 + triangle->side2 + triangle->side3;
}

static void triangle_display_info(const Shape* shape) {
    const Triangle* triangle = (const Triangle*)shape;
    printf("Shape: %s\n", triangle->base.name);
    printf("Sides: %.2f, %.2f, %.2f, Area: %.2f, Perimeter: %.2f\n",
           triangle->side1, triangle->side2, triangle->side3,
           triangle_calculate_area(shape),
           triangle_calculate_perimeter(shape));
}

static const ShapeVTable triangle_vtable = {
    .calculate_area = triangle_calculate_area,
    .calculate_perimeter = triangle_calculate_perimeter,
    .display_info = triangle_display_info
};

Triangle* triangle_create(double side1, double side2, double side3) {
    Triangle* triangle = (Triangle*)malloc(sizeof(Triangle));
    if (!triangle) return NULL;
    
    triangle->base.name = "Triangle";
    triangle->base.vtable = &triangle_vtable;
    triangle->side1 = side1;
    triangle->side2 = side2;
    triangle->side3 = side3;
    
    return triangle;
}

void triangle_destroy(Triangle* triangle) {
    free(triangle);
}

double triangle_get_side1(const Triangle* triangle) {
    return triangle ? triangle->side1 : 0.0;
}

double triangle_get_side2(const Triangle* triangle) {
    return triangle ? triangle->side2 : 0.0;
}

double triangle_get_side3(const Triangle* triangle) {
    return triangle ? triangle->side3 : 0.0;
}

实际使用

c 复制代码
// main.c - 多态演示
#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
#include "triangle.h"

void demonstrate_polymorphism() {
    printf("=== C Language Polymorphism Demo ===\n\n");
    
    // 创建不同类型的形状对象
    Shape* shapes[4];
    shapes[0] = (Shape*)circle_create(5.0);
    shapes[1] = (Shape*)rectangle_create(4.0, 6.0);
    shapes[2] = (Shape*)triangle_create(3.0, 4.0, 5.0);
    shapes[3] = (Shape*)circle_create(2.5);
    
    // 统一接口操作不同类型的对象 - 多态的核心
    printf("Individual Shape Information:\n");
    for (int i = 0; i < 4; i++) {
        shape_display_info(shapes[i]);
        printf("---\n");
    }
    
    // 计算总面积 - 多态的威力体现
    printf("Calculating total area using polymorphism:\n");
    double total_area = 0.0;
    for (int i = 0; i < 4; i++) {
        double area = shape_calculate_area(shapes[i]);
        printf("%s area: %.2f\n", shape_get_name(shapes[i]), area);
        total_area += area;
    }
    printf("Total Area: %.2f\n\n", total_area);
    
    // 计算总周长
    printf("Calculating total perimeter using polymorphism:\n");
    double total_perimeter = 0.0;
    for (int i = 0; i < 4; i++) {
        double perimeter = shape_calculate_perimeter(shapes[i]);
        printf("%s perimeter: %.2f\n", shape_get_name(shapes[i]), perimeter);
        total_perimeter += perimeter;
    }
    printf("Total Perimeter: %.2f\n\n", total_perimeter);
    
    // 演示运行时类型识别和特定操作
    printf("Type-specific operations:\n");
    for (int i = 0; i < 4; i++) {
        const char* name = shape_get_name(shapes[i]);
        if (name) {
            if (strcmp(name, "Circle") == 0) {
                Circle* circle = (Circle*)shapes[i];
                printf("Circle radius: %.2f\n", circle_get_radius(circle));
            }
            else if (strcmp(name, "Rectangle") == 0) {
                Rectangle* rect = (Rectangle*)shapes[i];
                printf("Rectangle dimensions: %.2f x %.2f\n",
                       rectangle_get_width(rect), rectangle_get_height(rect));
            }
            else if (strcmp(name, "Triangle") == 0) {
                Triangle* triangle = (Triangle*)shapes[i];
                printf("Triangle sides: %.2f, %.2f, %.2f\n",
                       triangle_get_side1(triangle),
                       triangle_get_side2(triangle),
                       triangle_get_side3(triangle));
            }
        }
    }
    
    // 清理内存
    for (int i = 0; i < 4; i++) {
        const char* name = shape_get_name(shapes[i]);
        if (name) {
            if (strcmp(name, "Circle") == 0) {
                circle_destroy((Circle*)shapes[i]);
            }
            else if (strcmp(name, "Rectangle") == 0) {
                rectangle_destroy((Rectangle*)shapes[i]);
            }
            else if (strcmp(name, "Triangle") == 0) {
                triangle_destroy((Triangle*)shapes[i]);
            }
        }
    }
}

// 工厂函数示例 - 基于输入创建不同对象
Shape* shape_factory(const char* type, ...) {
    // 简化实现,实际应用中需要处理可变参数
    if (strcmp(type, "circle") == 0) {
        return (Shape*)circle_create(1.0);  // 默认半径
    }
    else if (strcmp(type, "rectangle") == 0) {
        return (Shape*)rectangle_create(1.0, 1.0);  // 默认尺寸
    }
    else if (strcmp(type, "triangle") == 0) {
        return (Shape*)triangle_create(1.0, 1.0, 1.0);  // 默认边长
    }
    return NULL;
}

int main() {
    demonstrate_polymorphism();
    return 0;
}

嵌入式开发中实际案例介绍

1. STM32 HAL库中的驱动多态

c 复制代码
// 通用设备接口
typedef struct {
    void (*init)(void* device);
    void (*deinit)(void* device);
    HAL_StatusTypeDef (*start)(void* device);
    HAL_StatusTypeDef (*stop)(void* device);
    HAL_StatusTypeDef (*read)(void* device, uint8_t* data, uint16_t size);
    HAL_StatusTypeDef (*write)(void* device, uint8_t* data, uint16_t size);
} DeviceOperations;

// UART设备
typedef struct {
    DeviceOperations ops;  // 操作接口
    UART_HandleTypeDef huart;
    uint8_t* rx_buffer;
    uint16_t rx_size;
} UARTDevice;

// I2C设备  
typedef struct {
    DeviceOperations ops;  // 操作接口
    I2C_HandleTypeDef hi2c;
    uint8_t dev_addr;
} I2CDevice;

// SPI设备
typedef struct {
    DeviceOperations ops;  // 操作接口
    SPI_HandleTypeDef hspi;
    GPIO_TypeDef* cs_port;
    uint16_t cs_pin;
} SPIDevice;

// 多态使用 - 统一设备操作接口
void device_operation_demo() {
    DeviceOperations* devices[3];
    
    // 初始化不同设备
    UARTDevice uart_dev;
    I2CDevice i2c_dev;
    SPIDevice spi_dev;
    
    // 设置各自的操作函数
    uart_dev.ops.init = uart_init;
    uart_dev.ops.write = uart_write;
    // ... 其他操作
    
    i2c_dev.ops.init = i2c_init;
    i2c_dev.ops.write = i2c_write;
    // ... 其他操作
    
    spi_dev.ops.init = spi_init;
    spi_dev.ops.write = spi_write;
    // ... 其他操作
    
    devices[0] = &uart_dev.ops;
    devices[1] = &i2c_dev.ops;
    devices[2] = &spi_dev.ops;
    
    // 统一初始化所有设备 - 多态调用
    for (int i = 0; i < 3; i++) {
        devices[i]->init(devices[i]);
    }
    
    // 统一数据传输 - 每个设备调用自己的write实现
    uint8_t data[] = {0x01, 0x02, 0x03};
    for (int i = 0; i < 3; i++) {
        devices[i]->write(devices[i], data, sizeof(data));
    }
}

2. FreeRTOS中的任务多态

c 复制代码
// 任务基类接口
typedef struct {
    void (*create)(void* task, const char* name, uint32_t stack_size, UBaseType_t priority);
    void (*run)(void* task);
    void (*cleanup)(void* task);
    TaskHandle_t handle;
} TaskInterface;

// 通信任务
typedef struct {
    TaskInterface base;
    QueueHandle_t msg_queue;
    void (*send_message)(void* task, void* msg);
    void* (*receive_message)(void* task);
} CommTask;

// 定时任务
typedef struct {
    TaskInterface base;
    TimerHandle_t timer;
    void (*start_timer)(void* task, TickType_t period);
    void (*timer_callback)(void* task);
} TimerTask;

// 控制任务
typedef struct {
    TaskInterface base;
    SemaphoreHandle_t control_sem;
    void (*acquire_control)(void* task);
    void (*release_control)(void* task);
} ControlTask;

// 多态任务管理
void task_management_demo() {
    TaskInterface* tasks[3];
    
    CommTask comm_task;
    TimerTask timer_task;
    ControlTask control_task;
    
    // 设置各自的任务函数
    comm_task.base.run = comm_task_run;
    timer_task.base.run = timer_task_run;
    control_task.base.run = control_task_run;
    
    tasks[0] = &comm_task.base;
    tasks[1] = &timer_task.base;
    tasks[2] = &control_task.base;
    
    // 统一创建任务
    for (int i = 0; i < 3; i++) {
        tasks[i]->create(tasks[i], "Task", 1000, 1);
    }
    
    // 任务运行时的多态行为由FreeRTOS调度器处理
    // 每个任务运行时会调用自己的run函数
}

3. LVGL中的控件多态

c 复制代码
// 控件基类虚函数表
typedef struct {
    lv_res_t (*signal_cb)(struct _lv_obj_t * obj, lv_signal_t sign, void * param);
    lv_res_t (*design_cb)(struct _lv_obj_t * obj, const lv_area_t * mask, lv_design_mode_t mode);
    lv_res_t (*event_cb)(struct _lv_obj_t * obj, lv_event_t event);
} lv_obj_class_vtable_t;

// 基础对象类
extern const lv_obj_class_vtable_t lv_obj_vtable;

// 按钮类
extern const lv_obj_class_vtable_t lv_btn_vtable;

// 标签类
extern const lv_obj_class_vtable_t lv_label_vtable;

// 在实际使用中,LVGL通过对象的class指针实现多态
void lvgl_polymorphism_demo() {
    lv_obj_t * obj1 = lv_obj_create(lv_scr_act(), NULL);
    lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
    lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL);
    
    // 设置相同的事件回调,但不同对象类型会有不同行为
    lv_obj_set_event_cb(obj1, generic_event_handler);
    lv_obj_set_event_cb(btn1, generic_event_handler);
    lv_obj_set_event_cb(label1, generic_event_handler);
    
    // 当事件发生时,每个对象会根据其class调用相应的signal_cb
    // 实现多态的事件处理
}

// 统一的事件处理函数
static lv_res_t generic_event_handler(lv_obj_t * obj, lv_event_t event) {
    // 获取对象的类
    const lv_obj_class_vtable_t* vtable = obj->class_p;
    
    // 调用特定于类的信号处理
    if (vtable && vtable->signal_cb) {
        return vtable->signal_cb(obj, event, NULL);
    }
    
    return LV_RES_OK;
}

4. Contiki-NG中的协议多态

c 复制代码
// 网络协议接口
typedef struct {
    void (*input)(void* protocol, void* packet, uint16_t len);
    void (*output)(void* protocol, void* packet, uint16_t len);
    void (*init)(void* protocol);
} NetworkProtocol;

// IPv6协议实现
typedef struct {
    NetworkProtocol base;
    uip_ds6_netif_t netif;
    // IPv6特定方法
    void (*neighbor_solicitation)(void* ipv6);
} IPv6Protocol;

// RPL路由协议实现
typedef struct {
    NetworkProtocol base;
    rpl_dag_t dag;
    // RPL特定方法
    void (*local_repair)(void* rpl);
} RPLProtocol;

// 6LoWPAN协议实现
typedef struct {
    NetworkProtocol base;
    // 6LoWPAN特定方法
    void (*fragment)(void* protocol, void* packet);
} SixlowpanProtocol;

// 多态协议栈处理
void protocol_stack_demo() {
    NetworkProtocol* protocols[3];
    
    IPv6Protocol ipv6;
    RPLProtocol rpl;
    SixlowpanProtocol sixlowpan;
    
    // 设置协议操作
    ipv6.base.input = ipv6_input;
    ipv6.base.output = ipv6_output;
    
    rpl.base.input = rpl_input;
    rpl.base.output = rpl_output;
    
    sixlowpan.base.input = sixlowpan_input;
    sixlowpan.base.output = sixlowpan_output;
    
    protocols[0] = &ipv6.base;
    protocols[1] = &rpl.base;
    protocols[2] = &sixlowpan.base;
    
    // 统一初始化
    for (int i = 0; i < 3; i++) {
        protocols[i]->init(protocols[i]);
    }
    
    // 数据包多态处理
    void* packet = create_test_packet();
    for (int i = 0; i < 3; i++) {
        protocols[i]->input(protocols[i], packet, 100);
    }
}

5. Zephyr RTOS中的驱动多态

c 复制代码
// 统一设备驱动API
struct device_driver_api {
    int (*init)(const struct device *dev);
    int (*read)(const struct device *dev, uint32_t *value);
    int (*write)(const struct device *dev, uint32_t value);
};

// GPIO驱动API
struct gpio_driver_api {
    struct device_driver_api base;
    // GPIO特定操作
    int (*pin_configure)(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags);
    int (*pin_get)(const struct device *dev, gpio_pin_t pin, uint32_t *value);
};

// I2C驱动API
struct i2c_driver_api {
    struct device_driver_api base;
    // I2C特定操作
    int (*transfer)(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr);
};

// SPI驱动API
struct spi_driver_api {
    struct device_driver_api base;
    // SPI特定操作
    int (*transceive)(const struct device *dev, const struct spi_config *config, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs);
};

// 多态设备访问
void zephyr_device_demo() {
    const struct device *devices[] = {
        device_get_binding("GPIO_0"),
        device_get_binding("I2C_0"),
        device_get_binding("SPI_0")
    };
    
    // 统一初始化所有设备
    for (int i = 0; i < 3; i++) {
        const struct device_driver_api *api = 
            (const struct device_driver_api *)devices[i]->api;
        api->init(devices[i]);
    }
    
    // 多态读取操作
    uint32_t value;
    for (int i = 0; i < 3; i++) {
        const struct device_driver_api *api = 
            (const struct device_driver_api *)devices[i]->api;
        if (api->read) {
            api->read(devices[i], &value);
        }
    }
}

6. 嵌入式MQTT客户端多态

c 复制代码
// 网络传输层接口
typedef struct {
    int (*connect)(void* transport, const char* host, int port);
    int (*disconnect)(void* transport);
    int (*send)(void* transport, const void* data, size_t len);
    int (*receive)(void* transport, void* buffer, size_t len);
} TransportInterface;

// TCP传输实现
typedef struct {
    TransportInterface base;
    int socket_fd;
    struct sockaddr_in server_addr;
} TCPTransport;

// SSL/TLS传输实现
typedef struct {
    TransportInterface base;
    SSL* ssl_handle;
    SSL_CTX* ssl_ctx;
    // TLS特定方法
    int (*verify_certificate)(void* tls);
} TLSTransport;

// WebSocket传输实现
typedef struct {
    TransportInterface base;
    // WebSocket特定方法
    int (*handshake)(void* websocket);
} WebSocketTransport;

// MQTT客户端可以使用不同的传输层
void mqtt_transport_demo() {
    TransportInterface* transports[3];
    
    TCPTransport tcp;
    TLSTransport tls;
    WebSocketTransport ws;
    
    // 设置传输操作
    tcp.base.connect = tcp_connect;
    tcp.base.send = tcp_send;
    
    tls.base.connect = tls_connect;
    tls.base.send = tls_send;
    
    ws.base.connect = ws_connect;
    ws.base.send = ws_send;
    
    transports[0] = &tcp.base;
    transports[1] = &tls.base;
    transports[2] = &ws.base;
    
    // MQTT客户端可以透明地使用任何传输层
    MQTTClient mqtt_client;
    for (int i = 0; i < 3; i++) {
        mqtt_client.transport = transports[i];
        mqtt_connect(&mqtt_client, "mqtt.broker.com", 1883);
        // 使用相同的MQTT接口,底层传输自动选择相应实现
    }
}

总结

差异原因

  1. C++原生多态:通过虚函数表和继承关系由编译器自动处理,支持动态绑定

  2. C语言模拟:需要手动实现函数指针表和类型转换,运行时通过函数指针调用实现多态

  3. 类型安全:C++提供类型安全的向下转型(dynamic_cast),C语言需要手动类型检查和转换

模拟特点

  1. 函数指针表:通过结构体中的函数指针表模拟虚函数表

  2. 显式类型转换:需要在基类和派生类之间进行显式类型转换

  3. 接口统一:通过统一的函数接口操作不同对象

  4. 运行时绑定:通过函数指针在运行时决定调用哪个具体实现

  5. 内存布局:依赖结构体第一个成员是基类的内存布局约定

这种多态模拟方式在嵌入式系统中非常重要,它允许在资源受限的环境下实现灵活的软件架构,支持模块化设计和代码复用,是嵌入式软件工程中的高级技术。

相关推荐
hui函数3 小时前
python全栈(基础篇)——day03:后端内容(字符串格式化+简单数据类型转换+进制的转换+运算符+实战演示+每日一题)
开发语言·后端·python·全栈
寻星探路3 小时前
Java EE初阶启程记09---多线程案例(2)
java·开发语言·java-ee
froginwe114 小时前
Python 3 输入和输出
开发语言
小何好运暴富开心幸福4 小时前
C++之再谈类与对象
开发语言·c++·vscode
zhangfeng11334 小时前
R 导出 PDF 时中文不显示 不依赖 showtext** 的最简方案(用 extrafont 把系统 TTF 真正灌进 PDF 内核)
开发语言·r语言·pdf·生物信息
应用市场4 小时前
自建本地DNS过滤系统:实现局域网广告和垃圾网站屏蔽
开发语言·php
郝学胜-神的一滴4 小时前
中秋特别篇:使用QtOpenGL和着色器绘制星空与满月
开发语言·c++·算法·软件工程·着色器·中秋
Predestination王瀞潞4 小时前
Python oct() 函数
开发语言·python
生物小卡拉5 小时前
R脚本--PCA分析系列1_v1.0
开发语言·r语言