1.简介
单例模式(Singleton Pattern)是设计模式中的一种,用于确保一个类只有一个实例,并提供一个全局访问点。在面向对象编程语言(如C++或Java)中,单例模式常用于限制某个类的实例数量,使得在整个应用程序中该类的实例唯一。在C语言中,我们可以通过一些巧妙的方式来实现这一模式,虽然C语言本身并不支持面向对象的特性。
2.通俗讲解
想象一下,你是一个城市的市长。作为市长,你不希望你的城市有多个市长,因为这会导致混乱。因此,你决定制定一项政策:无论在城市的任何地方,任何时候,大家只能找到一个市长。如果市民们需要找市长处理问题,他们总是可以通过一个固定的号码联系到你,而不会因为多个市长而感到困惑。
在程序设计中,这个“市长”就是单例模式中的“实例”,而那个“固定号码”就是全局访问点。我们通过单例模式来确保程序中某个重要的对象(比如配置管理器、日志记录器等)只有一个实例,并且这个实例可以被全局访问。
3.实战
3.1.代码
在C语言中,实现单例模式的关键在于使用静态变量和控制实例的创建。下面是一个简单的C语言实现示例:
#include <stdio.h>
#include <stdlib.h>
// 单例类
typedef struct {
int value;
} Singleton;
// 静态变量,保存唯一实例
static Singleton* instance = NULL;
// 获取单例实例的函数
Singleton* getInstance() {
if (instance == NULL) { // 如果实例还没有被创建
instance = (Singleton*)malloc(sizeof(Singleton)); // 分配内存
instance->value = 0; // 初始化
printf("Singleton instance created.\n");
}
return instance;
}
// 销毁单例实例的函数
void destroyInstance() {
if (instance != NULL) {
free(instance); // 释放内存
instance = NULL; // 将实例指针置空
printf("Singleton instance destroyed.\n");
}
}
int main() {
// 获取并使用单例实例
Singleton* s1 = getInstance();
s1->value = 42;
printf("s1 value: %d\n", s1->value);
// 再次获取实例,确保是同一个实例
Singleton* s2 = getInstance();
printf("s2 value: %d\n", s2->value); // 应该输出42,因为s1和s2是同一个实例
// 销毁实例
destroyInstance();
return 0;
}
3.2.代码解析
-
静态实例指针:static Singleton* instance = NULL;
静态变量 instance 用于存储单例实例。这是一个全局变量,但仅限于在当前文件中可见,确保外部无法直接访问和修改它。 -
获取实例的函数:Singleton* getInstance()
这个函数检查 instance 是否为空。如果为空,则分配内存并初始化实例;否则,直接返回已有的实例。这样保证了在整个程序运行期间,无论调用多少次 getInstance,返回的都是同一个实例。 -
销毁实例的函数:void destroyInstance()
当程序不再需要这个单例实例时,可以通过这个函数释放内存并将 instance 指针置空。这样可以避免内存泄漏,并确保程序可以在必要时重新创建实例。 -
主函数:
在主函数中,我们演示了如何获取和使用单例实例。s1 和 s2 是通过 getInstance 函数获取的两个指针,它们实际上指向同一个内存地址,因此对 s1 的操作也会影响 s2,反之亦然。
3.3.代码运行
Singleton instance created.
s1 value: 42
s2 value: 42
Singleton instance destroyed.
3.4.结果分析
- “Singleton instance created.”:表示第一次调用 getInstance() 时,成功创建了单例实例。
- “s1 value: 42” 和 “s2 value: 42”:显示了 s1 和 s2 指针都指向了同一个实例,所以无论是通过 s1 还是 s2 访问 value 成员,结果都是 42。
- “Singleton instance destroyed.”:表示调用 destroyInstance() 后,单例实例被成功销毁,释放了内存。
4.总结
单例模式是非常有用的设计模式之一,特别是在需要控制资源的使用、确保某些操作的全局一致性时。在C语言中,虽然没有类的概念,但我们可以通过静态变量和适当的内存管理技巧来实现单例模式。这不仅让代码更具结构性,也提高了程序的可维护性和稳定性。
通过这种方式,我们可以确保在整个程序中,某个重要的资源(如配置管理器、日志系统等)始终只有一个实例,从而避免资源竞争和数据不一致的情况。