c++ 设计模式---结构型模式(用三句话讲清楚每一个模式)---1

本文介绍了五种经典的设计模式,包括适配器模式、桥接模式、组合模式、装饰模式及外观模式,每种模式都有其特定的应用场景和解决的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,ADAPTER 适配器

      适配器的概念:适配器就是一个接口转换器:像电源适配器,笔记本的电源适配器把220v的电源变为笔记本的12v直流电源。程序也一样,也要接口转换器(Adapter),把已经存在的对象或类(Adaptee)转化成我们需要的类(target)。         

      分为类适配器对象适配器

      类适配器使用多重继承对一个接口与另一个接口进行匹配。如图:

 

 

       对象匹配器依赖于对象组合,如图:

 

   

 

二,BRIDGE 桥接

      将抽象部分与它的实现部分分离,使它们都可以独立地变化。我的理解是:将抽象(Abstraction)中的子抽象(Implementor)独立出来,用子抽象的对象(imp)来实现抽象。比如:书是一个抽象,子抽象是工具,A工具用生产纸质文字书,B工具用来生产精装图画书,    抽象调用子抽象实现它的功能。

 

三,COMPOSITE(组合)

     对单个对象和组合对象的使用具有一致性(都看成组合)。我的理解是:要把所有(component)对象当成组合对象(component)。比如:积木,一个积木A或者B是积木,几个积木(A+B+C)组合的也是积木。何不把单个积木也看成是积木的组合。

   

 

四,DECORATOR (装饰)

   动态地给一个对象添加一些额外的职责。这个大概是最好理解的一个模式之一。假设我制作一个本书,做好了(称之为A书),一会想再给它加个封面(还是书,称之为B书),之后再给它加个保护套(还是书,称之为C书),现在我们想做C书,哪的先做出A,再加上封面,再加上保护套就可以了。

 

五,FACADE(外观)

    为子系统中的一组接口提供一个一致的界面:

 

 六,PROXY(代理)

    明星不是有代理人么,一些不适合明星直接去做的事情(明星太忙了,或者会引起骚乱),会由代理人去做,程序也一样,一些不适合某个类直接去做的事,找一个代理类来做。

<think>嗯,用户之前问过C++的多态,现在又想知道单例模式。先确定用户是不是在继续深入设计模式的学习?可能他们正在学习面向对象设计,或者准备面试需要掌握常见的设计模式。 单例模式属于创建型模式,确保一个类只有一个实例,并提供全局访问点。用户可能想知道如何实现,需要注意什么,以及应用场景。但得考虑他们可能对多线程安全、延迟初始化等细节不太清楚。 之前的回答结构清晰,分层次讲解,这次也应该保持类似结构。先讲本质,再讲实现方式,关键点,应用场景,注意事项。还要注意C++的实现,因为用户之前的问题是关于C++的。 用户可能对懒汉式和饿汉式区别不太明白,需要解释清楚。同时,内存释放问题,比如使用智能指针还是手动删除,可能也需要提及。多线程环境下双重检查锁定是否安全,现代C++是否有更好的方法,比如C++11之后的局部静态变量线程安全。 可能需要注意提醒用户单例的潜在缺点,比如测试困难,违反单一职责原则,是否过度使用。需要给出实际例子,比如配置管理器、日志记录器等,帮助理解应用场景。 要确保LaTeX格式正确,用户之前的回答中使用了代码块,这里也要用代码示例展示不同实现方式。同时,注意系统级指令中的格式要求,行内公式用$...$,独立公式用$$...$$,但这个问题可能不太涉及数学公式,所以可能不需要用。 总结,回答结构应该是:定义、实现方式(懒汉、饿汉)、关键机制(静态实例、私有构造)、应用场景、注意事项、示例代码。还要提到现代C++的最佳实践,比如使用智能指针或者C++11的特性来简化线程安全的实现。</think>以下是对单例模式的详细解析,采用分层递进的结构: 一、设计本质 单例模式(Singleton Pattern)是创建型设计模式,核心目标: 1. 保证类**仅有一个实例**存在 2. 提供**全局访问点** 3. 控制资源共用(如配置文件、线程池等) 二、经典实现方式 ```cpp class Singleton { private: static Singleton* instance; // 静态成员变量 Singleton() {} // 私有构造函数 Singleton(const Singleton&) = delete; // 禁止拷贝 Singleton& operator=(const Singleton&) = delete; // 禁止赋值 public: static Singleton* getInstance() { if (!instance) { instance = new Singleton(); } return instance; } }; // 静态成员初始化 Singleton* Singleton::instance = nullptr; ``` 三、关键实现要素 1. **私有构造函数**:阻止外部创建实例 2. **静态成员变量**:存储唯一实例 3. **静态访问方法**:控制实例创建 4. **防拷贝机制**:禁用拷贝构造和赋值运算符 四、多线程安全改进 1. 双重检查锁定(Double-Checked Locking): ```cpp std::mutex mtx; // 互斥锁 static Singleton* getInstance() { if (!instance) { // 第一次检查 std::lock_guard<std::mutex> lock(mtx); if (!instance) { // 第二次检查 instance = new Singleton(); } } return instance; } ``` 2. C++11后更简洁的线程安全实现: ```cpp static Singleton& getInstance() { static Singleton instance; // 线程安全的局部静态变量 return instance; } ``` 五、变体形式对比 | 类型 | 初始化时机 | 线程安全 | 内存管理 | |-----------|-------------|------|------------| | 懒汉式 | 首次调用时初始化 | 需加锁 | 需手动释放 | | 饿汉式 | 程序启动时初始化 | 安全 | 随程序生命周期释放 | | Meyers式 | C++11局部静态变量 | 安全 | 自动释放 | 六、典型应用场景 1. 配置信息管理器(全局唯一配置源) 2. 日志记录系统(集中处理日志输出) 3. 设备驱动访问(如打印机后台服务) 4. 连接池/线程池管理 七、注意事项 1. **测试困难**:单例状态全局共享,测试用例相互影响 2. **违反单一职责**:同时承担创建和管理实例的职责 3. **生命周期管理**:需明确何时销毁实例 4. **过度使用风险**:可能变成全局变量替代品 八、现代C++改进方案(使用智能指针) ```cpp class Singleton { private: static std::unique_ptr<Singleton> instance; // ...其他成员与之前相同 public: static Singleton* getInstance() { if (!instance) { instance = std::make_unique<Singleton>(); } return instance.get(); } }; ``` 九、UML类图示意 ``` [Singleton] |- instance: static Singleton* |- Singleton() |+ getInstance(): static Singleton* ``` 十、模式优缺点分析 ✓ **优点**: - 严格控实例数量 - 减少全局变量污染 - 允许灵活扩展(如改为多例模式) ✗ **缺点**: - 引入全局状态 - 违反开闭原则(通过继承扩展困难) - 多线程环境复杂度增加 理解单例模式的关键在于把握其**控制实例化过程**的核心机制,在需要严格管控资源访问或保证唯一性的场景中合理使用,同时注意避免将其作为全局变量的替代方案过度使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值