当前位置: 首页 > news >正文

C语言模拟面向对象编程方法之继承

目录

    • C++ 中继承
      • 继承的介绍:
      • 继承的用途:
      • 继承使用实例
    • C语言模拟面向对象继承
      • 模拟过程
      • 实际使用
    • 嵌入式开发中实际案例介绍
      • 1. STM32 HAL库中的设备继承
      • 2. FreeRTOS中的任务继承
      • 3. LVGL中的控件继承体系
      • 4. Contiki-NG中的协议栈继承
      • 5. Zephyr RTOS中的驱动继承模型
      • 6. 嵌入式MQTT客户端继承架构
    • 总结
      • 差异原因
      • 模拟特点

C++ 中继承

继承的介绍:

继承是面向对象编程的三大特性之一,它允许我们依据另一个类来定义一个类,使得创建和维护应用程序变得更加容易。通过继承,子类可以获得父类的属性和方法,同时可以添加自己特有的属性和方法

继承的意义:

  • 提高代码复用性:子类可以直接使用父类的功能
  • 提高代码扩展性:子类可以在父类基础上进行扩展
  • 建立类之间的层次关系:体现现实世界中的"is-a"关系

继承类型:

  • 公有继承(public):父类的公有和保护成员在子类中保持原有访问级别
  • 保护继承(protected):父类的公有和保护成员在子类中变为保护级别
  • 私有继承(private):父类的公有和保护成员在子类中变为私有级别

继承的用途:

  • 代码重用:避免重复编写相同的代码
  • 功能扩展:在现有类基础上添加新功能
  • 多态基础:为运行时多态提供基础
  • 层次建模:建立现实世界的层次关系模型

继承使用实例

// 基类:交通工具
class Vehicle {
protected:std::string brand;int speed;int capacity;public:Vehicle(const std::string& b, int s, int c) : brand(b), speed(s), capacity(c) {}virtual void displayInfo() const {std::cout << "Brand: " << brand << ", Speed: " << speed << " km/h"<< ", Capacity: " << capacity << " people" << std::endl;}virtual void start() {std::cout << brand << " is starting..." << std::endl;}std::string getBrand() const { return brand; }int getSpeed() const { return speed; }
};// 派生类:汽车
class Car : public Vehicle {
private:int doors;std::string fuelType;public:Car(const std::string& b, int s, int c, int d, const std::string& f): Vehicle(b, s, c), doors(d), fuelType(f) {}void displayInfo() const override {Vehicle::displayInfo();std::cout << "Doors: " << doors << ", Fuel: " << fuelType << std::endl;}void honk() {std::cout << brand << " car is honking!" << std::endl;}
};// 派生类:自行车
class Bicycle : public Vehicle {
private:int gears;bool hasBasket;public:Bicycle(const std::string& b, int s, int c, int g, bool basket): Vehicle(b, s, c), gears(g), hasBasket(basket) {}void displayInfo() const override {Vehicle::displayInfo();std::cout << "Gears: " << gears << ", Has Basket: " << (hasBasket ? "Yes" : "No") << std::endl;}void ringBell() {std::cout << brand << " bicycle is ringing bell!" << std::endl;}
};// 使用
Car car("Toyota", 180, 5, 4, "Gasoline");
Bicycle bike("Giant", 25, 1, 21, true);car.start();        // 继承自Vehicle
car.honk();         // Car特有方法
car.displayInfo();  // 重写的方法bike.start();       // 继承自Vehicle  
bike.ringBell();    // Bicycle特有方法
bike.displayInfo(); // 重写的方法

C语言模拟面向对象继承

C语言没有原生继承支持,但可以通过结构体组合和函数指针来模拟继承关系。核心思想是将父类结构体作为子类结构体的第一个成员,这样可以通过内存布局实现类似继承的效果

模拟过程

// vehicle.h - 基类头文件
#ifndef VEHICLE_H
#define VEHICLE_Htypedef struct Vehicle Vehicle;// 基类公共接口
Vehicle* vehicle_create(const char* brand, int speed, int capacity);
void vehicle_destroy(Vehicle* vehicle);void vehicle_display_info(const Vehicle* vehicle);
void vehicle_start(Vehicle* vehicle);
const char* vehicle_get_brand(const Vehicle* vehicle);
int vehicle_get_speed(const Vehicle* vehicle);
int vehicle_get_capacity(const Vehicle* vehicle);#endif // VEHICLE_H
// vehicle.c - 基类实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vehicle.h"// 基类结构体定义
struct Vehicle {char brand[50];int speed;int capacity;// 虚函数表指针(模拟多态)void (*display_info)(const Vehicle*);void (*start)(Vehicle*);
};// 基类方法实现
static void vehicle_display_info_impl(const Vehicle* vehicle) {printf("Brand: %s, Speed: %d km/h, Capacity: %d people\n",vehicle->brand, vehicle->speed, vehicle->capacity);
}static void vehicle_start_impl(Vehicle* vehicle) {printf("%s is starting...\n", vehicle->brand);
}// 基类构造函数
Vehicle* vehicle_create(const char* brand, int speed, int capacity) {Vehicle* vehicle = (Vehicle*)malloc(sizeof(Vehicle));if (!vehicle) return NULL;strncpy(vehicle->brand, brand, sizeof(vehicle->brand) - 1);vehicle->brand[sizeof(vehicle->brand) - 1] = '\0';vehicle->speed = speed;vehicle->capacity = capacity;// 设置默认方法实现vehicle->display_info = vehicle_display_info_impl;vehicle->start = vehicle_start_impl;return vehicle;
}void vehicle_destroy(Vehicle* vehicle) {free(vehicle);
}// 基类公共方法
void vehicle_display_info(const Vehicle* vehicle) {if (vehicle && vehicle->display_info) {vehicle->display_info(vehicle);}
}void vehicle_start(Vehicle* vehicle) {if (vehicle && vehicle->start) {vehicle->start(vehicle);}
}const char* vehicle_get_brand(const Vehicle* vehicle) {return vehicle ? vehicle->brand : NULL;
}int vehicle_get_speed(const Vehicle* vehicle) {return vehicle ? vehicle->speed : 0;
}int vehicle_get_capacity(const Vehicle* vehicle) {return vehicle ? vehicle->capacity : 0;
}
// car.h - 派生类头文件
#ifndef CAR_H
#define CAR_H#include "vehicle.h"typedef struct Car Car;// 派生类公共接口
Car* car_create(const char* brand, int speed, int capacity, int doors, const char* fuel_type);
void car_destroy(Car* car);void car_honk(Car* car);
int car_get_doors(const Car* car);
const char* car_get_fuel_type(const Car* car);// 继承基类接口
#define car_display_info(car) vehicle_display_info((Vehicle*)(car))
#define car_start(car) vehicle_start((Vehicle*)(car))
#define car_get_brand(car) vehicle_get_brand((Vehicle*)(car))#endif // CAR_H
// car.c - 派生类实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "car.h"// 派生类结构体 - 第一个成员是基类
struct Car {Vehicle base;  // 基类作为第一个成员,实现内存布局继承int doors;char fuel_type[20];
};// 派生类重写的方法
static void car_display_info_impl(const Vehicle* vehicle) {const Car* car = (const Car*)vehicle;  // 安全转换printf("Brand: %s, Speed: %d km/h, Capacity: %d people\n",car->base.brand, car->base.speed, car->base.capacity);printf("Doors: %d, Fuel: %s\n", car->doors, car->fuel_type);
}static void car_start_impl(Vehicle* vehicle) {Car* car = (Car*)vehicle;printf("%s car is starting with %s fuel...\n", car->base.brand, car->fuel_type);
}// 派生类构造函数
Car* car_create(const char* brand, int speed, int capacity, int doors, const char* fuel_type) {Car* car = (Car*)malloc(sizeof(Car));if (!car) return NULL;// 初始化基类部分strncpy(car->base.brand, brand, sizeof(car->base.brand) - 1);car->base.brand[sizeof(car->base.brand) - 1] = '\0';car->base.speed = speed;car->base.capacity = capacity;// 设置派生类重写的方法car->base.display_info = car_display_info_impl;car->base.start = car_start_impl;// 初始化派生类特有成员car->doors = doors;strncpy(car->fuel_type, fuel_type, sizeof(car->fuel_type) - 1);car->fuel_type[sizeof(car->fuel_type) - 1] = '\0';return car;
}void car_destroy(Car* car) {free(car);
}// 派生类特有方法
void car_honk(Car* car) {if (car) {printf("%s car is honking!\n", car->base.brand);}
}int car_get_doors(const Car* car) {return car ? car->doors : 0;
}const char* car_get_fuel_type(const Car* car) {return car ? car->fuel_type : NULL;
}
// bicycle.h - 另一个派生类
#ifndef BICYCLE_H
#define BICYCLE_H#include "vehicle.h"typedef struct Bicycle Bicycle;Bicycle* bicycle_create(const char* brand, int speed, int capacity,int gears, int has_basket);
void bicycle_destroy(Bicycle* bicycle);void bicycle_ring_bell(Bicycle* bicycle);
int bicycle_get_gears(const Bicycle* bicycle);
int bicycle_has_basket(const Bicycle* bicycle);// 继承基类接口
#define bicycle_display_info(bicycle) vehicle_display_info((Vehicle*)(bicycle))
#define bicycle_start(bicycle) vehicle_start((Vehicle*)(bicycle))#endif // BICYCLE_H
// bicycle.c - 另一个派生类实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bicycle.h"struct Bicycle {Vehicle base;  // 基类作为第一个成员int gears;int has_basket;
};static void bicycle_display_info_impl(const Vehicle* vehicle) {const Bicycle* bicycle = (const Bicycle*)vehicle;printf("Brand: %s, Speed: %d km/h, Capacity: %d people\n",bicycle->base.brand, bicycle->base.speed, bicycle->base.capacity);printf("Gears: %d, Has Basket: %s\n", bicycle->gears, bicycle->has_basket ? "Yes" : "No");
}static void bicycle_start_impl(Vehicle* vehicle) {Bicycle* bicycle = (Bicycle*)vehicle;printf("%s bicycle is starting... pedal ready!\n", bicycle->base.brand);
}Bicycle* bicycle_create(const char* brand, int speed, int capacity,int gears, int has_basket) {Bicycle* bicycle = (Bicycle*)malloc(sizeof(Bicycle));if (!bicycle) return NULL;// 初始化基类部分strncpy(bicycle->base.brand, brand, sizeof(bicycle->base.brand) - 1);bicycle->base.brand[sizeof(bicycle->base.brand) - 1] = '\0';bicycle->base.speed = speed;bicycle->base.capacity = capacity;// 设置重写方法bicycle->base.display_info = bicycle_display_info_impl;bicycle->base.start = bicycle_start_impl;// 初始化派生类特有成员bicycle->gears = gears;bicycle->has_basket = has_basket;return bicycle;
}void bicycle_destroy(Bicycle* bicycle) {free(bicycle);
}void bicycle_ring_bell(Bicycle* bicycle) {if (bicycle) {printf("%s bicycle is ringing bell!\n", bicycle->base.brand);}
}int bicycle_get_gears(const Bicycle* bicycle) {return bicycle ? bicycle->gears : 0;
}int bicycle_has_basket(const Bicycle* bicycle) {return bicycle ? bicycle->has_basket : 0;
}

实际使用

// main.c - 测试继承模拟
#include <stdio.h>
#include "vehicle.h"
#include "car.h"
#include "bicycle.h"void demonstrate_inheritance() {printf("=== Demonstrating Inheritance in C ===\n\n");// 创建基类对象Vehicle* generic_vehicle = vehicle_create("Generic", 100, 4);printf("Generic Vehicle:\n");vehicle_display_info(generic_vehicle);vehicle_start(generic_vehicle);printf("\n");// 创建派生类对象Car* car = car_create("Toyota", 180, 5, 4, "Gasoline");Bicycle* bicycle = bicycle_create("Giant", 25, 1, 21, 1);// 使用继承的方法printf("Car (using inherited methods):\n");car_display_info(car);  // 通过宏调用基类方法car_start(car);         // 重写的方法printf("Bicycle (using inherited methods):\n");bicycle_display_info(bicycle);bicycle_start(bicycle);printf("\n");// 使用派生类特有方法printf("Car specific methods:\n");car_honk(car);printf("Doors: %d, Fuel: %s\n", car_get_doors(car), car_get_fuel_type(car));printf("Bicycle specific methods:\n");bicycle_ring_bell(bicycle);printf("Gears: %d, Has Basket: %s\n",bicycle_get_gears(bicycle), bicycle_has_basket(bicycle) ? "Yes" : "No");printf("\n");// 演示多态效果 - 通过基类指针操作不同派生类对象printf("=== Polymorphism Demo ===\n");Vehicle* vehicles[] = {(Vehicle*)car,(Vehicle*)bicycle,generic_vehicle};for (int i = 0; i < 3; i++) {printf("Vehicle %d: ", i + 1);vehicle_display_info(vehicles[i]);vehicle_start(vehicles[i]);}// 清理内存vehicle_destroy(generic_vehicle);car_destroy(car);bicycle_destroy(bicycle);
}int main() {demonstrate_inheritance();return 0;
}

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

1. STM32 HAL库中的设备继承

// 通用设备基类模拟
typedef struct {uint32_t base_address;uint32_t clock_control;void (*init)(void* device);void (*deinit)(void* device);HAL_StatusTypeDef (*start)(void* device);HAL_StatusTypeDef (*stop)(void* device);
} Device_Base;// UART设备派生类
typedef struct {Device_Base base;           // 继承基类UART_InitTypeDef init;      // UART特有配置uint8_t* tx_buffer;uint16_t tx_size;// UART特有方法HAL_StatusTypeDef (*transmit)(void* uart, uint8_t* data, uint16_t size);HAL_StatusTypeDef (*receive)(void* uart, uint8_t* data, uint16_t size);
} UART_Device;// SPI设备派生类  
typedef struct {Device_Base base;           // 继承基类SPI_InitTypeDef init;       // SPI特有配置GPIO_TypeDef* cs_port;uint16_t cs_pin;// SPI特有方法HAL_StatusTypeDef (*transmit_receive)(void* spi, uint8_t* tx, uint8_t* rx, uint16_t size);
} SPI_Device;// 使用示例
UART_Device uart1;
SPI_Device spi1;// 统一通过基类接口操作
uart1.base.start(&uart1);
spi1.base.start(&spi1);// 使用派生类特有接口
uart1.transmit(&uart1, data, sizeof(data));
spi1.transmit_receive(&spi1, tx_data, rx_data, size);

2. FreeRTOS中的任务继承

// 基础任务结构
typedef struct {TaskHandle_t handle;TaskFunction_t function;const char* name;uint32_t stack_depth;UBaseType_t priority;// 基础方法BaseType_t (*create)(void* task);void (*delete)(void* task);void (*delay)(void* task, TickType_t ticks);
} BaseTask;// 通信任务派生类
typedef struct {BaseTask base;              // 继承基础任务QueueHandle_t queue;SemaphoreHandle_t mutex;// 通信特有方法BaseType_t (*send_message)(void* task, void* msg, TickType_t timeout);BaseType_t (*receive_message)(void* task, void* msg, TickType_t timeout);
} CommTask;// 定时任务派生类
typedef struct {BaseTask base;              // 继承基础任务  TimerHandle_t timer;TickType_t period;// 定时特有方法BaseType_t (*start_timer)(void* task);BaseType_t (*stop_timer)(void* task);
} TimerTask;

3. LVGL中的控件继承体系

// 基础对象结构
struct _lv_obj_t {struct _lv_obj_t * parent;lv_ll_t child_ll;lv_area_t coords;lv_style_list_t style_list;// 虚函数表lv_signal_cb_t signal_cb;lv_design_cb_t design_cb;lv_event_cb_t event_cb;
};// 按钮控件 - 继承基础对象
typedef struct {lv_obj_t obj;               // 继承基础对象lv_btn_state_t state;lv_style_list_t style_btn;// 按钮特有方法void (*set_state)(lv_obj_t* btn, lv_btn_state_t state);lv_btn_state_t (*get_state)(const lv_obj_t* btn);
} lv_btn_t;// 标签控件 - 继承基础对象
typedef struct {lv_obj_t obj;               // 继承基础对象char* text;lv_label_align_t align;lv_style_list_t style_text;// 标签特有方法void (*set_text)(lv_obj_t* label, const char* text);const char* (*get_text)(const lv_obj_t* label);
} lv_label_t;// 使用继承关系
lv_btn_t* btn = lv_btn_create(lv_scr_act(), NULL);
lv_label_t* label = lv_label_create(btn, NULL);  // 标签作为按钮的子对象// 通过基类指针操作所有控件
lv_obj_set_size((lv_obj_t*)btn, 100, 50);
lv_obj_set_pos((lv_obj_t*)label, 10, 10);

4. Contiki-NG中的协议栈继承

// 基础网络协议结构
typedef struct network_protocol {const char* name;uint8_t protocol_id;// 基础方法void (*init)(void* protocol);void (*input)(void* protocol, void* packet);void (*output)(void* protocol, void* packet);
} network_protocol_t;// IPv6协议派生类
typedef struct {network_protocol_t base;    // 继承基础协议uip_ds6_netif_t netif;uip_ds6_addr_t addrs;// IPv6特有方法void (*set_address)(void* ipv6, uip_ip6addr_t* addr);void (*add_route)(void* ipv6, uip_ip6addr_t* network);
} ipv6_protocol_t;// RPL路由协议派生类
typedef struct {network_protocol_t base;    // 继承基础协议rpl_dag_t dag;rpl_instance_t instance;// RPL特有方法void (*join_dag)(void* rpl, uip_ip6addr_t* dag_id);void (*local_repair)(void* rpl);
} rpl_protocol_t;

5. Zephyr RTOS中的驱动继承模型

// 基础设备驱动结构
struct device_driver_api {int (*init)(const struct device* dev);int (*configure)(const struct device* dev, uint32_t config);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;  // 继承基础API// 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);int (*pin_set)(const struct device* dev, gpio_pin_t pin, uint32_t value);
};// I2C驱动派生API
struct i2c_driver_api {struct device_driver_api base;  // 继承基础API// I2C特有方法int (*transfer)(const struct device* dev, struct i2c_msg* msgs, uint8_t num_msgs, uint16_t addr);int (*configure)(const struct device* dev, uint32_t dev_config);
};// 使用统一的设备接口访问不同驱动
const struct device* gpio_dev = device_get_binding("GPIO_0");
const struct device* i2c_dev = device_get_binding("I2C_0");// 通过基类API操作
gpio_dev->api->init(gpio_dev);
i2c_dev->api->init(i2c_dev);

6. 嵌入式MQTT客户端继承架构

// 基础网络客户端
typedef struct {const char* server_url;int port;int socket_fd;// 基础网络方法int (*connect)(void* client);int (*disconnect)(void* client);int (*send)(void* client, const void* data, size_t len);int (*receive)(void* client, void* buffer, size_t len);
} NetworkClient;// MQTT客户端派生类
typedef struct {NetworkClient base;         // 继承网络客户端const char* client_id;MQTTVersion version;// MQTT特有方法int (*publish)(void* mqtt, const char* topic, const void* payload, size_t len, int qos);int (*subscribe)(void* mqtt, const char* topic, int qos);int (*unsubscribe)(void* mqtt, const char* topic);
} MQTTClient;// CoAP客户端派生类
typedef struct {NetworkClient base;         // 继承网络客户端coap_uri_t server_uri;// CoAP特有方法int (*get)(void* coap, const char* path, void* response, size_t* response_len);int (*put)(void* coap, const char* path, const void* data, size_t len);int (*observe)(void* coap, const char* path, coap_response_handler_t handler);
} CoAPClient;

总结

差异原因

  1. C++原生继承:通过class Derived : public Base语法直接支持,编译器处理内存布局和虚函数表

  2. C语言模拟:通过结构体组合实现,将基类结构体作为派生类的第一个成员

  3. 类型系统:C语言缺乏类型安全继承,需要手动类型转换

模拟特点

  1. 结构体组合:通过将基类结构体作为第一个成员实现内存布局继承

  2. 类型转换:通过强制类型转换在基类和派生类之间转换

  3. 方法继承:通过函数指针和宏定义实现方法继承和重写

  4. 多态模拟:通过基类指针操作不同派生类对象实现多态

  5. 内存安全:需要手动管理类型转换的安全性

这种继承模拟方式在嵌入式系统中被广泛采用,它既保持了C语言的性能和资源效率,又获得了面向对象的代码组织和复用好处,是资源受限环境下实现复杂软件架构的重要手段。

http://www.dtcms.com/a/454740.html

相关文章:

  • jsp网站开发教学视频教程网站服务器租用报价
  • 西安网站建设品牌公司推荐网站建设 网页设计需要技能
  • 做端口映射 怎么访问网站南京百度网站排名
  • 【深度学习新浪潮】从“机械执行“到“智能决策“:大模型与办公Agent的融合实践
  • 网站备案和服务器备案吗常熟智能网站开发
  • 【量化开发】从0到1实现自己的量化算子系统
  • 扬中网站建设开发网站先做前台还是后台
  • 如何百度搜到自己网站免费素材免费下载
  • 自己搞网站建设wordpress 4.2.2 漏洞
  • 深圳自适应网站公司wordpress慕课
  • 扩散模型DDPM数学推导过程完整版(上)
  • 兰州网站seo外包详情页设计与制作
  • 单电源运放的使用
  • 硬件端之C++中class的所有常见写法、类
  • AI技术框架和应用领域简介
  • 企业免费自助建站系统百度seo排名帝搜软件
  • 网站建设的栏目规划seo教程搜索引擎优化
  • 微信小程序跳转到网站网站模板 外贸工厂
  • 做淘宝的网站有哪些内容做农业的公司管理网站
  • seo网站改版苏州企业网站公司都有哪些
  • 模板网站与定制网站的定位网页生成app制作
  • 网站 建设 开发 协议想要网站推广页
  • 周口网站建设哪家好优秀的定制网站建设提供商
  • 什么情况下需要建设网站微信手机网页版
  • 在印尼用哪个网站做电商商贸行业网站建设
  • 网站没快照优质公司网站
  • 酒店网站建站12306网站开发商
  • 袜子网站建设规划书爱民网站制作
  • 付网站建设费用 会计科目codex.wordpress.org
  • 第二十一章:调停纷争,化解干戈——Mediator的中介艺术