目录
-
- [C++ 中多态](#C++ 中多态)
- C语言模拟面向对象多态
- 嵌入式开发中实际案例介绍
-
- [1. STM32 HAL库中的驱动多态](#1. STM32 HAL库中的驱动多态)
- [2. FreeRTOS中的任务多态](#2. FreeRTOS中的任务多态)
- [3. LVGL中的控件多态](#3. LVGL中的控件多态)
- [4. Contiki-NG中的协议多态](#4. Contiki-NG中的协议多态)
- [5. Zephyr RTOS中的驱动多态](#5. Zephyr RTOS中的驱动多态)
- [6. 嵌入式MQTT客户端多态](#6. 嵌入式MQTT客户端多态)
- 总结
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接口,底层传输自动选择相应实现
}
}
总结
差异原因
-
C++原生多态:通过虚函数表和继承关系由编译器自动处理,支持动态绑定
-
C语言模拟:需要手动实现函数指针表和类型转换,运行时通过函数指针调用实现多态
-
类型安全:C++提供类型安全的向下转型(dynamic_cast),C语言需要手动类型检查和转换
模拟特点
-
函数指针表:通过结构体中的函数指针表模拟虚函数表
-
显式类型转换:需要在基类和派生类之间进行显式类型转换
-
接口统一:通过统一的函数接口操作不同对象
-
运行时绑定:通过函数指针在运行时决定调用哪个具体实现
-
内存布局:依赖结构体第一个成员是基类的内存布局约定
这种多态模拟方式在嵌入式系统中非常重要,它允许在资源受限的环境下实现灵活的软件架构,支持模块化设计和代码复用,是嵌入式软件工程中的高级技术。