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

发布于:2025-03-13 ⋅ 阅读:(20) ⋅ 点赞:(0)

面向对象与面向过程

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

封装

  在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;
}
  • 继承与抽象类
      含有纯虚函数的类,我们一般称之为抽象类。抽象类不能被实例化,实例化也没有意义,唯一的好处就是代码分层

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

  • 组合优于继承?

多态

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

深浅拷贝

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