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

面向对象与面向过程

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

封装

  在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.rhkb.cn/news/32624.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux_17进程控制

前提回顾&#xff1a; 页表可以将无序的物理地址映射为有序的; 通过进程地址空间&#xff0c;避免将内存直接暴漏给操作系统&#xff1b; cr3寄存器存放的有当前运行进程的页表的物理地址&#xff1b; 一、查看命令行参数和环境变量的地址 因为命令行参数和环境变量都是字符…

NVIDIA k8s-device-plugin源码分析与安装部署

在《kubernetes Device Plugin原理与源码分析》一文中&#xff0c;我们从源码层面了解了kubelet侧关于device plugin逻辑的实现逻辑&#xff0c;本文以nvidia管理GPU的开源github项目k8s-device-plugin为例&#xff0c;来看看设备插件侧的实现示例。 一、Kubernetes Device Pl…

MySql索引下推(ICP)是什么?有什么用?

目录 基本介绍为什么需要索引下推&#xff1f;未引入ICP&#xff08;x&#xff09;引入ICP&#xff08;√&#xff09; 如何指导sql优化适用场景sql优化 基本介绍 索引下推&#xff08;Index Condition Pushdown, ICP&#xff09;&#xff0c;是MySQL5.6 引入的优化技术&#…

用户可免费体验!国家超算互联网平台上线阿里开源推理模型接口服

近日&#xff0c;国家超算互联网平台上线阿里巴巴开源推理模型QwQ-32B API接口服务&#xff0c;现在用户可获得免费的100万Tokens。基于国产深算智能加速卡以及全国一体化算力网&#xff0c;平台支持海量用户便捷调用QwQ-32B、DeepSeek-R1等国产开源大模型的接口服务。 了解QwQ…

大数据学习(63)- Zookeeper详解

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91e; &#x1f…

【蓝桥杯python研究生组备赛】003 贪心

题目1 股票买卖 给定一个长度为 N 的数组&#xff0c;数组中的第 i 个数字表示一个给定股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&#xff09;。 注意&#xff1a;你不能同时参与多笔交易&…

mmdet3d.models.utils的clip_sigmoid理解

Sigmoid 函数 标准的 sigmoid 函数定义为&#xff1a; 容易得出结论&#xff1a; 取值范围(0, 1) clip_sigmoid 是在标准的 sigmoid 函数基础上进行 裁剪&#xff08;clip&#xff09;&#xff0c;即对 sigmoid 输出的结果加以限制&#xff0c;避免其超出特定范围。 import …

侯捷 C++ 课程学习笔记:进阶语法之lambda表达式(二)

侯捷 C 课程学习笔记&#xff1a;进阶语法之lambda表达式&#xff08;二&#xff09; 一、捕获范围界定 1. 局部变量与函数参数 ​非静态局部变量&#xff1a;Lambda 所在作用域内定义的局部变量&#xff08;如函数内部的 int x&#xff09;会被完整复制其当前值。捕获后外部变…

有必要使用 Oracle 向量数据库吗?

向量数据库最主要的特点是让传统的只能基于具体值/关键字的数据检索&#xff0c;进化到了可以直接基于语义的数据检索。这在AI时代至关重要&#xff01; 回到标题问题&#xff1a;是否有必要使用 Oracle 向量数据库&#xff1f; 这实际还要取决于你的具体应用需求。 客观来讲…

论文解读 | AAAI'25 CoRA:基于大型语言模型权重的协作信息感知用于推荐

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 个人信息 作者&#xff1a;刘禹廷&#xff0c;东北大学博士生 内容简介 将协作信息融入大型语言模型&#xff08;LLMs&#xff09;是一种有前景的适应推荐任务的技…

es扩容节点以后写入数据量增加1倍

背景&#xff1a; es扩容一倍的数据节点以后 写入数据量增加1倍 业务反馈业务访问量没增加。 最后定位是监控数据&#xff1a; PUT _cluster/settings {"persistent": {"xpack.monitoring.collection.enabled" : "false"} }这个索引记录的是 节…

G-Star 公益行 | 温暖相约 3.30 上海「开源×AI 赋能公益」Meetup

你是否曾想过&#xff0c;在这个数字化浪潮席卷的时代&#xff0c;公益组织如何突破技术瓶颈&#xff1f;当 AI 成为热门话题&#xff0c;它能为公益事业带来怎样的温度&#xff1f;开源的力量&#xff0c;如何让每一份善意都拥有无限可能&#xff1f; G-Star 公益行&#xff…

MySQL数据库复杂的增删改查操作

在前面的文章中&#xff0c;我们主要学习了数据库的基础知识以及基本的增删改查的操作。接下去将以一个比较实际的公司数据库为例子&#xff0c;进行讲解一些较为复杂且现时需求的例子。 基础知识&#xff1a; 一文清晰梳理Mysql 数据库基础知识_字段变动如何梳理清楚-CSDN博…

kafka-docker版

Kafka-docker版 1 概述 1.1 定义 Kafka传统定义&#xff1a; Kafka是一个分布式的基于发布/订阅模式的消息队列(MessageQucue)&#xff0c;主要应用于大数据实时处理领域。它是一个开源的分布式事件流平台( Event Streaming Platform)&#xff0c;被数千家公司用于高性能数据…

Zabbix 7.2 + Grafana 中文全自动安装ISO镜像

简介 ​ 基于Zabbix 官方的Alma Linux 8 作为基础镜像。 镜像源都改为国内大学镜像站&#xff0c;自动联网安装ZabbixGrafana。 安装中文字体、Zabbix和Grafana也配置默认中文。 Zabbix 也指定中文字体&#xff0c;绘图无乱码。 配置时区为东八区&#xff0c;Zabbix配置We…

使用pip在Windows机器上安装Open Webui,配合Ollama调用本地大模型

之前的文章分享过在 linux 服务器上安装&#xff0c;并使用Open-webui 来实现从页面上访问本地大模型的访问。也写了文章分享了我在家里 Windows Server 台式机上安装 Ollama 部署本地大模型&#xff0c;并分别使用 Chatbox 和 CherryStudio 来访问本地的大模型。今天我来分享一…

【python运行Janus-Pro-1B文生图功能】

前言 体验了一把本地部署Janus-Pro-1B实现文生图功能。 1、开源项目下载 官方开源项目代码直接从Github上下载。 2、模型下载 模型官方下载需要魔法 Janus-Pro-1B模型文件&#xff1a;Janus-Pro-1B模型文件 百度网盘&#xff1a; https://pan.baidu.com/s/16t4H4z-QZe2UDAg4…

18 | 实现简洁架构的 Handler 层

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b;欢迎加入 云原生 AI 实战 星球&#xff0c;12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;&#xff1b;本节课最终…

宇树ROS1开源模型在ROS2中Gazebo中仿真

以GO1为例 1. CMakelists.txt更新语法 cmake_minimum_required(VERSION 3.8) project(go1_description) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic) endif() # find dependencies find…

LearnOpenGL-笔记-其三

在之前的章节中我们学习了基本的窗口构建方法、着色器的定义与使用以及摄像机的构建&#xff0c;而从今天这个大章节开始我们要来学习光照有关的知识。 颜色 现实世界中有无数种颜色&#xff0c;每一个物体都有它们自己的颜色。我们需要使用&#xff08;有限的&#xff09;数…