这些设计模式在现代C++中如何应用

设计模式在现代C++中的应用

设计模式是解决常见软件设计问题的可重用模板。在现代C++(C++11 及更高版本)中,新特性如智能指针、lambda 表达式、移动语义和 std::function 等,使设计模式的实现更简洁、安全和高效。下面我将逐步介绍几种常见设计模式在现代C++中的应用,包括代码示例。每个模式会先简要描述,然后解释现代C++特性如何优化实现,并提供实际代码。

1. 单例模式(Singleton)

单例模式确保一个类只有一个实例,并提供全局访问点。在现代C++中,使用智能指针(如 std::unique_ptr)可以避免内存泄漏,并确保线程安全(通过 C++11 的 std::call_once)。

现代C++实现关键点

  • 使用 std::unique_ptr 管理实例。
  • std::call_once 保证线程安全的初始化。
  • 禁用拷贝和移动构造函数。
cpp 复制代码
#include <memory>
#include <mutex>

class Singleton {
private:
    static std::unique_ptr<Singleton> instance;
    static std::once_flag flag;

    Singleton() {} // 私有构造函数
    Singleton(const Singleton&) = delete; // 禁用拷贝
    Singleton& operator=(const Singleton&) = delete; // 禁用赋值

public:
    static Singleton& getInstance() {
        std::call_once(flag, []() {
            instance = std::make_unique<Singleton>();
        });
        return *instance;
    }

    void doSomething() {
        // 示例方法
    }
};

std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::once_flag Singleton::flag;

应用场景:全局配置管理或日志系统,确保只有一个实例共享资源。

2. 工厂模式(Factory)

工厂模式通过一个接口创建对象,而不指定具体类。现代C++中,lambda 表达式和 std::function 可以简化工厂的实现,避免复杂的继承层次。

现代C++实现关键点

  • 使用 std::function 存储创建函数。
  • 利用 lambda 表达式定义对象创建逻辑。
  • 结合 std::unordered_map 实现灵活的对象注册。
cpp 复制代码
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>

class Product {
public:
    virtual ~Product() = default;
    virtual void use() = 0;
};

class ConcreteProductA : public Product {
public:
    void use() override {
        // 实现A
    }
};

class ConcreteProductB : public Product {
public:
    void use() override {
        // 实现B
    }
};

class Factory {
private:
    std::unordered_map<std::string, std::function<std::unique_ptr<Product>()>> creators;

public:
    void registerCreator(const std::string& type, std::function<std::unique_ptr<Product>()> creator) {
        creators[type] = creator;
    }

    std::unique_ptr<Product> create(const std::string& type) {
        if (auto it = creators.find(type); it != creators.end()) {
            return it->second(); // 调用lambda创建对象
        }
        return nullptr;
    }
};

// 使用示例
int main() {
    Factory factory;
    factory.registerCreator("A", []() -> std::unique_ptr<Product> { return std::make_unique<ConcreteProductA>(); });
    factory.registerCreator("B", []() -> std::unique_ptr<Product> { return std::make_unique<ConcreteProductB>(); });

    auto product = factory.create("A");
    if (product) {
        product->use();
    }
}

应用场景:插件系统或依赖注入,动态创建不同类型的对象。

3. 观察者模式(Observer)

观察者模式定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者自动更新。现代C++中,std::function 和 lambda 表达式替代了传统的接口继承,使代码更灵活。

现代C++实现关键点

  • 使用 std::function 存储观察者回调。
  • 结合 std::vector 管理多个观察者。
  • 利用 lambda 简化事件处理。
cpp 复制代码
#include <functional>
#include <vector>
#include <iostream>

class Subject {
private:
    std::vector<std::function<void(int)>> observers;

public:
    void attach(std::function<void(int)> observer) {
        observers.push_back(observer);
    }

    void notify(int data) {
        for (auto& observer : observers) {
            observer(data); // 调用回调函数
        }
    }
};

// 使用示例
int main() {
    Subject subject;

    // 添加观察者1:使用lambda
    subject.attach([](int data) {
        std::cout << "Observer 1: " << data << std::endl;
    });

    // 添加观察者2:使用lambda
    subject.attach([](int data) {
        std::cout << "Observer 2: " << data << std::endl;
    });

    subject.notify(42); // 触发更新
}

应用场景:GUI 事件处理或实时数据监控,解耦发布者和订阅者。

4. 策略模式(Strategy)

策略模式定义一系列算法,并使它们可互换。现代C++中,std::function 或模板参数可以替代虚函数,减少运行时开销并提升灵活性。

现代C++实现关键点

  • 使用 std::function 封装策略函数。
  • 或使用模板在编译时绑定策略。
  • 避免虚函数开销。
cpp 复制代码
#include <functional>
#include <iostream>

class Context {
private:
    std::function<int(int, int)> strategy; // 策略函数

public:
    void setStrategy(std::function<int(int, int)> strat) {
        strategy = strat;
    }

    int executeStrategy(int a, int b) {
        return strategy(a, b);
    }
};

// 使用示例
int main() {
    Context context;

    // 策略1:加法
    context.setStrategy([](int a, int b) -> int { return a + b; });
    std::cout << "10 + 5 = " << context.executeStrategy(10, 5) << std::endl;

    // 策略2:乘法
    context.setStrategy([](int a, int b) -> int { return a * b; });
    std::cout << "10 * 5 = " << context.executeStrategy(10, 5) << std::endl;
}

应用场景:排序算法或支付方式选择,动态切换行为。

总结

在现代C++中,设计模式的应用变得更简洁和安全:

  • 优势 :智能指针管理内存,避免泄漏;lambda 和 std::function 替代继承,减少样板代码;移动语义提升性能。
  • 建议 :优先使用现代特性(如 C++17 的 std::optional 或 C++20 的 concepts)来简化模式实现。实际开发中,结合具体需求选择模式,避免过度设计。
  • 注意事项 :确保线程安全(使用 std::mutex 或原子操作),并遵循 RAII 原则(Resource Acquisition Is Initialization)管理资源。

通过以上示例,您可以看到现代C++如何使设计模式更易于实现和维护。如果需要深入某个模式或更多模式(如装饰器或适配器),请提供进一步细节!

相关推荐
qeen875 分钟前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
云烟成雨TD9 分钟前
Spring AI 1.x 系列【46】MCP Security 模块
java·人工智能·spring
CRMEB系统商城10 分钟前
CRMEB多商户系统(Java)v2.3公测版发布
java·开发语言·人工智能·小程序·开源·php
sinat_2554878117 分钟前
第七部分。介绍MVC(模型-视图-控制器)模式
java·ide·http·tomcat·intellij-idea
李白的天不白42 分钟前
ps -ef | grep java
java
ab_dg_dp1 小时前
Android 17+ 提取 AIDL 生成 Java 文件的实用脚本
android·java·python
王老师青少年编程1 小时前
信奥赛C++提高组csp-s之搜索进阶(记忆化搜索案例实践3)
c++·记忆化搜索·方格取数·csp·信奥赛·csp-s·提高组
超哥--1 小时前
B站视频内容智能分析系统(三):B站视频自动采集
java·开发语言·音视频·ai编程
郑洁文1 小时前
基于SpringBoot的商品仓库管理系统的设计与实现
java·spring boot·后端·仓库管理系统·商品仓库管理系统
布朗克1681 小时前
22 异常处理——从入门到精通的完整指南
java·异常处理