ESC
输入关键词搜索文章标题和内容

别再说C语言不能面向对象了!

本文由 linuxROS 整理发布,首发于 linuxros.cn,转载请注明出处。

别再说C语言不能面向对象了!

导读:很多同学觉得C语言没有Class、没有继承、没有多态,就写不出"高档"的代码。今天用struct+函数指针,带你实现全部23种设计模式。全篇代码可直接编译运行,适合想提升C语言工程能力的开发者。


一、原理简析

C语言实现面向对象的核心在于函数指针。通过struct存储数据,用函数指针模拟方法,可以完美模拟封装、继承、多态三大特性。

核心技巧一览:

OOP特性 C语言实现 作用
封装 struct + 函数指针 数据和方法打包
继承 结构体嵌套 子类首成员放父类
多态 函数指针数组 模拟vtable
内存管理 static / malloc 控制生命周期

二、实操步骤

2.1 单例模式:全局唯一实例

饿汉式(线程安全):

#include <stdio.h>

typedef struct Singleton {
    void (*show)(void);
} Singleton;

static Singleton g_instance;

void Singleton_Show(void) {
    printf("饿汉单例:全局唯一实例\n");
}

Singleton* GetSingletonInstance(void) {
    static int init_flag = 0;
    if (!init_flag) {
        g_instance.show = Singleton_Show;
        init_flag = 1;
    }
    return &g_instance;
}

int main(void) {
    Singleton *s1 = GetSingletonInstance();
    Singleton *s2 = GetSingletonInstance();
    printf("s1 == s2: %s\n", s1 == s2 ? "YES" : "NO");
    s1->show();
    return 0;
}

懒汉式(延迟加载):

来自 linuxros.cn · linuxROS
#include <stdio.h>
#include <stdlib.h>

typedef struct Singleton {
    void (*show)(void);
} Singleton;

static Singleton* g_lazy_instance = NULL;

Singleton* GetLazyInstance(void) {
    if (g_lazy_instance == NULL) {
        g_lazy_instance = (Singleton*)malloc(sizeof(Singleton));
        g_lazy_instance->show = /* 初始化 */;
    }
    return g_lazy_instance;
}

2.2 工厂模式:对象创建封装

简单工厂:

#include <stdio.h>
#include <string.h>

typedef struct Animal {
    void (*cry)(void);
} Animal;

void DogCry(void)  { printf("小狗:汪汪汪!\n"); }
void CatCry(void)  { printf("小猫:喵喵喵!\n"); }

Animal* CreateAnimal(const char* type) {
    static Animal dog = {DogCry};
    static Animal cat = {CatCry};
    if (strcmp(type, "dog") == 0) return &dog;
    if (strcmp(type, "cat") == 0) return &cat;
    return NULL;
}

2.3 建造者模式:分步构建

typedef struct Builder {
    void (*BuildWall)(House*);
    void (*BuildRoof)(House*);
    void (*BuildFloor)(House*);
    House* (*GetHouse)(void);
} Builder;

void DirectorConstruct(Builder* b, House* h) {
    b->BuildWall(h);
    b->BuildRoof(h);
    b->BuildFloor(h);
}

三、对比表格

饿汉式单例
线程安全 | 启动即创建 | 实现简单
↓
懒汉式单例
延迟加载 | 非线程安全 | 节省资源
↓
简单工厂
封装创建 | if-else分支 | 产品种类少
↓
抽象工厂
产品族 | 函数指针结构体 | 扩展方便

四、核心流程图

flowchart TB subgraph 创建型模式["创建型模式"] A["单例模式<br/>static变量"] B["工厂模式<br/>if-else分支"] C["建造者模式<br/>多函数指针"] D["原型模式<br/>Clone函数"] end A --> B B --> C C --> D

五、常见问题解决

问题 原因 解决方案
懒汉式线程不安全 多个线程同时判断NULL 使用双检锁或改用饿汉式
工厂新增产品需改代码 违反开闭原则 考虑策略模式替代
原型模式浅拷贝问题 指针成员未复制 实现深拷贝Clone函数

六、总结

本文介绍了5种创建型设计模式在C语言中的实现。通过struct+函数指针的组合,可以优雅地模拟面向对象的封装、继承、多态三大特性。

核心要点:
- static变量保证单例唯一性
- 工厂模式封装对象创建逻辑
- 建造者模式分步构建复杂对象
- 原型模式通过克隆创建新对象

下期预告:《C语言实现23种设计模式:结构型模式篇》—— 适配器、桥接、装饰器、组合模式详解。


关注公众号:linuxros
回复「设计模式」,获取完整23种设计模式C语言实现源码


程序员

版权声明

作者linuxROS
协议本作品采用 CC BY-NC-SA 4.0 许可协议:署名-非商业性使用-相同方式共享
关注欢迎关注微信公众号 linuxROS,获取更多机器人 / 嵌入式 / Linux 干货
返回首页