这些设计模式在现代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++如何使设计模式更易于实现和维护。如果需要深入某个模式或更多模式(如装饰器或适配器),请提供进一步细节!

相关推荐
t***5442 小时前
能否给出更多现代C++架构设计模式?
java·开发语言·c++
それども2 小时前
Spring Boot 切面无法切进来的原因
java·spring·dubbo
mjhcsp2 小时前
C++信息论超详解析
开发语言·c++
随风,奔跑2 小时前
Spring Cloud Alibaba学习笔记(一)
java·后端·spring cloud
此生只爱蛋2 小时前
【CAD】Parasolid:CAD的os
c++
無限進步D2 小时前
Java 基础算法训练
java·开发语言·算法·入门
map1e_zjc2 小时前
Java SpringBoot学习记录(4)
java·开发语言·学习
小毛驴8502 小时前
多线程同步打标记的几种实现方案
java·开发语言·python
Mr_Xuhhh2 小时前
递归之美:合并两个有序链表的优雅解法
java·开发语言