嵌入式八股C语言---面向对象篇

news/2025/3/15 14:17:56/

面向对象与面向过程

  • 面向过程
    就是把整个业务逻辑分成多个步骤,每步或每一个功能都可以使用一个函数来实现
  • 面向对象
    对象是类的实例化,此时一个类就内部有属性和相应的方法

封装

  在C语言里实现封装就是实现一个结构体,里面包括的成员变量和函数指针,然后在构造函数中,为结构体的函数指针赋初值
对于这个函数指针往往会把自身传入,因为只是在模仿class

#include <stdio.h>
#include <stdlib.h>
struct student
{int height;char* name;void(*add_height)(struct student *, int);
};void ADD_HEIGHT(struct student * stu, int add)
{stu->height += add;
}
struct student * Student(int height,char *name)
{struct student * stu = malloc(sizeof(struct student));if(stu) {stu->height = height;stu->name = name;stu->add_height = ADD_HEIGHT;}return stu;
}
void freeStudent(struct student * stu )
{if(stu) {free(stu);stu = NULL;}
}
int main()
{struct student * stu = Student(180,"LCS");printf("%d\r\n",stu->height);stu->add_height(stu,50);printf("%d\r\n",stu->height);return 0;
}

继承

  • 实现方案一: 子类中嵌套父类结构体指针
    C语言模仿继承就是子类的结构体里嵌套一个父类的结构体
    那如何实现类似虚函数的效果呢–修改父类的函数指针的指向就行
 		#include <stdio.h>#include <stdlib.h>struct animal{/* data */int age;void (*speak)(void);};void cat_speak() {printf("speak miaomiao\r\n");}void dog_speak() {printf("speak wangwang\r\n");}struct cat {struct animal * anm;int like_nothing;};struct dog {struct animal * anm;int like_eat_shit;};struct animal* Animal(int age) {struct animal* anm = malloc(sizeof(struct animal));anm->age = age;anm->speak = NULL;return anm;}struct cat* Cat(int age) {struct cat* new_cat = malloc(sizeof(struct cat));new_cat->anm = Animal(age); // 这就意味着等会你释放内存是真麻烦new_cat->like_nothing = 1;new_cat->anm->speak = cat_speak;return new_cat;}struct dog* Dog(int age) {struct dog* new_dog = malloc(sizeof(struct dog));new_dog->anm = Animal(age); // 这就意味着等会你释放内存是真麻烦new_dog->like_eat_shit = 1;new_dog->anm->speak = dog_speak;return new_dog;}int main(){struct cat* new_cat = Cat(5);struct dog* new_dog = Dog(10);new_cat->anm->speak();new_dog->anm->speak();return 0;}
  • 继承的妙用: struct list_head 双向链表
      当我们想要实现自己的列表的实现 就把自己的链表中嵌入这个双向列表就行
  • 实现方案二: 父类提供一个void * 私有指针 不同的子类把void * 做不同的实现
#include <stdio.h>
#include <stdlib.h>// 基类定义
typedef struct {int age;void (*speak)(void*); // 虚函数指针void* private_data;   // 用于存储子类特定数据
} Animal;// Cat的私有数据结构
typedef struct {int like_nothing;
} CatPrivate;// Dog的私有数据结构
typedef struct {int like_eat_shit;
} DogPrivate;// 实现虚函数:猫叫声
static void cat_speak(void* obj) {CatPrivate* private_data = ((Animal*)obj)->private_data;printf("Cat says: miaomiao, like_nothing=%d\n", private_data->like_nothing);
}// 实现虚函数:狗叫声
static void dog_speak(void* obj) {DogPrivate* private_data = ((Animal*)obj)->private_data;printf("Dog says: wangwang, like_eat_shit=%d\n", private_data->like_eat_shit);
}// 创建Animal实例
Animal* create_animal(int age, void (*speak_func)(void*), void* private_data) {Animal* animal = malloc(sizeof(Animal));animal->age = age;animal->speak = speak_func;animal->private_data = private_data; // 设置私有数据return animal;
}// 创建Cat实例
Animal* create_cat(int age) {CatPrivate* cat_private = malloc(sizeof(CatPrivate));cat_private->like_nothing = 1; // 设定Cat私有数据Animal* animal = create_animal(age, cat_speak, cat_private);return animal;
}// 创建Dog实例
Animal* create_dog(int age) {DogPrivate* dog_private = malloc(sizeof(DogPrivate));dog_private->like_eat_shit = 1; // 设定Dog私有数据Animal* animal = create_animal(age, dog_speak, dog_private);return animal;
}int main() {Animal* new_cat = create_cat(5);Animal* new_dog = create_dog(10);// 调用虚函数new_cat->speak(new_cat);new_dog->speak(new_dog);// 清理资源free(((CatPrivate*)new_cat->private_data));free(((DogPrivate*)new_dog->private_data));free(new_cat);free(new_dog);return 0;
}
  • 继承与抽象类
      含有纯虚函数的类,我们一般称之为抽象类。抽象类不能被实例化,实例化也没有意义,唯一的好处就是代码分层

  • 公共继承 私有继承 保护继承
    在这里插入图片描述

  • 组合优于继承?

多态

  用父类指针调用子类的成员函数
  那就是给结构体的成员变量的函数指针指向不同的函数

深浅拷贝

  浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,
  深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针


http://www.ppmy.cn/news/1579328.html

相关文章

吴恩达机器学习笔记复盘(三)Jupyter NoteBook

Jupyter NoteBook Jupyter是一个开源的交互式计算环境&#xff1a; 特点 交互式编程&#xff1a;支持以单元格为单位编写和运行代码&#xff0c;用户可以实时看到代码的执行结果&#xff0c;便于逐步调试和理解代码逻辑。多语言支持&#xff1a;不仅支持Python&#xff0c;还…

【Python】07、列表

文章目录 1.列表的简介2.切片3.通用操作3.1 和 * 操作3.2 in 、not in 操作3.3 len()3.4 min()、max()3.4 index()、count()方法 4.序列5.修改列表&#xff08;可变序列&#xff09;5.1. 通过索引修改5.2. 通过切片修改 6.列表的方法6.1 append()6.2 insert()6.3 extend()6.4 …

vue 仿deepseek前端开发一个对话界面

后端&#xff1a;调用deepseek的api&#xff0c;所以返回数据格式和deepseek相同 {"model": "DeepSeek-R1-Distill-Qwen-1.5B", "choices": [{"index": 0, "delta": {"role": "assistant", "cont…

69.Harmonyos NEXT图片预览组件应用实践(二):电商、内容与办公场景

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; Harmonyos NEXT图片预览组件应用实践&#xff08;二&#xff09;&#xff1a;电商、内容与办公场景 文章目录 Harmonyos NEXT图片预览组件应用实践…

根据Excel快速生成表的创建以及新增数据记录的sql

目录 前言一、下载Excel二、使用步骤(以自增版为例)1.生成建表sql1.1.在"table结构表"创建表结构1.2.确认区域1.3.获取建表sql 2.生成新增数据记录sql2.1.维护新增的数据2.2.处理新增的数据2.3.获取sql语句 总结 前言 在Excel软件中&#xff0c;根据维护的表结构与数…

HTTP 协议中常见的错误状态码(详细介绍)

以下是 HTTP 协议中常见的错误状态码及其原因的总结&#xff0c;按错误类型分类整理&#xff1a; 4xx 客户端错误 400 Bad Request 原因&#xff1a;请求格式错误&#xff0c;服务器无法解析。常见场景&#xff1a; 请求头或请求体语法错误&#xff08;如 JSON/XML 格式错误…

Linux 部署 Spring Boot 项目, Web项目(2025版)

Linux 部署 Spring Boot 项目&#xff0c;Web项目&#xff08;2025版&#xff09; 一、简洁版1.1 Linux 环境配置1.2 将Spring Boot 项目部署到 Linux 中 二、详细版2.1 Linux 环境配置2.2 Spring Boot 项目搭建2.3 mysql 配置2.4 测试项目2.5 将Spring Boot 项目部署到 Linux …

Maven | 站在初学者的角度配置

目录 Maven 是什么 概述 常见错误 创建错误代码示例 正确代码示例 Maven 的下载 Maven 依赖源 Maven 环境 环境变量 CMD测试 Maven 文件配置 本地仓库 远程仓库 Maven 工程创建 IDEA配置Maven IDEA Maven插件 Maven 是什么 概述 Maven是一个项目管理和构建自…