别再说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语言实现源码