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

news2025/4/21 21:28:05

面向对象与面向过程

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

封装

  在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.coloradmin.cn/o/2314603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# ListView设置标题头背景颜色和字体颜色

一、向ListView 添加数据 for (int i 1; i < 5; i) {ListViewItem litem new ListViewItem("data:"i);lv_WarnList.Items.Add(litem); }如果需要在ListView中绑定实体类对象的话&#xff0c;需要将数据放在Tag属性里 for (int i 1; i < 5; i) {AngleData …

嵌入式 ARM Linux 系统构成(6):应用层(Application Layer)

目录 一、应用层概述 二、应用层的核心组成 2.1 主应用程序&#xff08;Main Applications&#xff09; 2.2 系统服务&#xff08;System Services&#xff09; 2.3 用户界面&#xff08;User Interface&#xff09; 2.4 脚本与自动化工具 2.5 第三方库与框架 2.6 通信…

【HTML】一、基础标签

文章目录 1、开发环境准备2、html介绍3、html基本骨架4、标签的关系5、常用标签5.1 标题5.2 段落5.3 换行与水平线5.4 文本格式化标签5.5 图像标签5.6 超链接标签5.7 音频标签5.8 视频标签 6、路径7、网页制作 1、开发环境准备 在编辑器中写代码&#xff0c;在浏览器中看效果 …

centos7通过yum安装redis

centos7通过yum安装redis 1.安装redis数据库 yum install -y redis2.启动redis服务 systemctl start redis3.查看redis状态 systemctl status redis4、停止服务 systemctl stop redis5、重启服务 systemctl restart redis6、查看redis进程 ps -ef | grep redis7、开放端…

AutoMQ x OSS 的 Iceberg 数据入湖的最佳实践

背景 在数字化转型进程中&#xff0c;用户交互行为产生的多维度数据已成为企业的重要战略资产。以短视频平台为例&#xff0c;基于用户点赞事件的实时推荐算法能显著提升用户活跃度和平台粘性。这类实时数据主要通过 Apache Kafka 流处理平台进行传输&#xff0c;通过其扇出&a…

【Help Manual】导出PDF中英文不在一行解决方案

在使用Help Manual 的时候&#xff0c;会出现导出PDF时&#xff0c;中英文在同一行出现水平不对齐的问题。如下&#xff1a; 解决方案&#xff1a; 结果如下&#xff1a;

Scala编程_实现Rational的基本操作

在Scala中实现一个简单的有理数&#xff08;Rational&#xff09;类&#xff0c;并对其进行加法、比较等基本操作. 有理数的定义 有理数是可以表示为两个整数的比值的数&#xff0c;通常形式为 n / d&#xff0c;其中 n 是分子&#xff0c;d 是分母。为了确保我们的有理数始终…

用python和Pygame库实现“跳过障碍”游戏

用python和Pygame库实现“跳过障碍”游戏 游戏开发 跳过障碍游戏流程说明&#xff1a; 启动游戏后显示开始界面&#xff08;包含游戏说明&#xff09; 按空格键进入游戏 游戏过程中躲避障碍物获取分数 碰撞后显示结束界面&#xff08;包含最终得分&#xff09; 按空格键…

SqlServer数据库报错紧急或可疑无法访问的修复过程,亲测有效。

当 SQL Server 数据库被标记为 SUSPECT 状态时&#xff0c;表示数据库可能由于事务日志损坏、数据文件丢失或其他严重问题而无法正常启动。以下是一个详细的恢复步骤&#xff0c;基于搜索结果中的信息和常见的最佳实践&#xff1a; 恢复步骤 1. 确认数据库状态 将database-n…

【python-uiautomator2】手机上的ATX应用界面报错问题处理:无法提供服务,非am instrument启动

目录 一、前期准备 1.1 插入设备 1.2 安装atx-agent 二、解决报错&#xff1a;无法提供服务&#xff0c;非am instrument启动 2.1 出现报错 2.2 尝试解决 2.3 最终解决 三、开启ATX的悬浮窗权限 一、前期准备 1.1 插入设备 本地插入待执行设备&#xff0c;待执行设备…

子母钟系统,京准电子科技助力高考精准计时

子母钟系统&#xff0c;京准电子科技助力高考精准计时 子母钟系统&#xff0c;京准电子科技助力高考精准计时 【摘要】子母钟系统又叫网络时钟系统是校园网络中一个重要的精准计时系统&#xff0c;随着网络的普及&#xff0c;许多校园都建了自己的校园专网&#xff0c;使用的…

深度解析:主流大模型与智能体框架能力对比及实战指南

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。https://www.captainbed.cn/north 文章目录 一、技术演进全景图二、主流大模型能力矩阵1. 闭源模型对比2. 开源模型对比 三、智能体框架深…

Linux中的基本指令(下)

目录 mv指令 more指令 less指令 head指令 tail 指令 继续理解文件 重定向和追加重定向操作 理解管道 find指令 whereis 指令 bc指令 uname ‒r指令 grep 指令 关机 扩展命令 zip/unzip 指令 tar指令 关于rzsz 系统间的文件互传 接上&#xff01; mv指令 m…

第十七:go 反射

fmt.printf("%T"&#xff0c;obj) // 打印 reflect 的类型 fmt.Printf("%T", obj) // *reflect.rtype //打印的是一个指针类型 reflect包 在Go语言中反射的相关功能由内置的reflect包提供&#xff0c;任意接口值在反射中都可以理解为由reflect.Type和…

【RabbitMQ】Spring Boot 结合 RabbitMQ 完成应用间的通信

&#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【中间件】企业级中间件剖析 Spring 框架与 RabbitMQ 的整合主要通过 Spring AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;模块实现&#xff0c;提供了便捷的消息队列开发能力。 引…

Pytorch系列教程:可视化Pytorch模型训练过程

深度学习和理解训练过程中的学习和进步机制对于优化性能、诊断欠拟合或过拟合等问题至关重要。将训练过程可视化的过程为学习的动态提供了有价值的见解&#xff0c;使我们能够做出合理的决策。训练进度必须可视化的两种方法是&#xff1a;使用Matplotlib和Tensor Board。在本文…

electron+vue+webview内嵌网页并注入js

vue内嵌网页可以使用iframe实现内嵌网页&#xff0c;但是只能通过postMessage间接通信&#xff0c;在electron环境下&#xff0c;vue可以直接使用webview来内嵌网页&#xff0c;支持 executeJavaScript、postMessage、send 等丰富的通信机制。 使用 webview的优势 性能更佳&…

利用OpenResty拦截SQL注入

需求 客户的一个老项目被相关部门检测不安全&#xff0c;报告为sql注入。不想改代码&#xff0c;改项目&#xff0c;所以想到利用nginx去做一些数据校验拦截。也就是前端传一些用于sql注入的非法字符或者数据库的关键字这些&#xff0c;都给拦截掉&#xff0c;从而实现拦截sql…

CAD文件转换为STL

AutoCAD与STL格式简介 AutoCAD软件是由美国欧特克有限公司&#xff08;Autodesk&#xff09;出品的一款自动计算机辅助设计软件&#xff0c;可以用于绘制二维制图和基本三维设计&#xff0c;通过它无需懂得编程&#xff0c;即可自动制图&#xff0c;因此它在全球广泛使用&…

QT:串口上位机

创建工程 布局UI界面 设置名称 设置数据 设置波特率 波特率默认9600 设置数据位 数据位默认8 设置停止位 设置校验位 调整串口设置、接收设置、发送设置为Group Box 修改配置 QT core gui serialport 代码详解 mianwindow.h 首先在mianwindow.h当中定义一个串口指…