c++的设计模式(常用)

1. 单例模式 (Singleton)

这是 C++ 中使用频率极高的模式。

作用: 确保一个类只有一个实例,并提供一个全局访问点。

应用场景: 日志管理器、配置管理器、线程池、数据库连接池。

C++ 注意点: 需要特别注意线程安全。C++11 及以后,推荐使用"局部静态变量"实现(Meyers Singleton),由编译器保证线程安全,代码简洁且无需手动加锁

代码举例:

cpp 复制代码
#include <iostream>
#include <string>

class ConfigManager {
public:
    // 获取唯一实例的接口
    static ConfigManager& getInstance() {
        // C++11 保证静态局部变量初始化是线程安全的
        static ConfigManager instance; 
        return instance;
    }

    // 删除拷贝构造和赋值操作,防止意外复制
    ConfigManager(const ConfigManager&) = delete;
    ConfigManager& operator=(const ConfigManager&) = delete;

    void setConfig(const std::string& key, const std::string& value) {
        std::cout << "设置配置: " << key << " = " << value << std::endl;
        // 实际存储逻辑...
    }

private:
    // 私有构造函数和析构函数
    ConfigManager() { std::cout << "配置管理器初始化\n"; }
    ~ConfigManager() { std::cout << "配置管理器销毁\n"; }
};

// --- 使用示例 ---
int main() {
    // 获取实例 (无论调用多少次,都是同一个对象)
    auto& config1 = ConfigManager::getInstance();
    auto& config2 = ConfigManager::getInstance();

    // 地址相同,证明是同一个实例
    std::cout << &config1 << " == " << &config2 << std::endl; 

    config1.setConfig("Volume", "80%");
    return 0;
}

2. 工厂模式 (Factory)

用于解耦对象的创建过程,主要包含两种变体:

简单工厂 (Simple Factory): 通过传入参数决定创建哪种具体产品。虽然常用,但增加新产品时需要修改工厂类,违反开闭原则。

工厂方法 (Factory Method): 定义一个创建对象的接口,但让子类决定实例化哪一个类(如 Creator 类派生出 ConcreteCreator)。

应用场景: 游戏中的角色生成器、不同数据库驱动的连接创建

代码举例:

cpp 复制代码
#include <iostream>
#include <memory>

// 产品接口
class Product {
public:
    virtual ~Product() = default;
    virtual void use() = 0;
};

// 具体产品 A
class ConcreteProductA : public Product {
public:
    void use() override {
        std::cout << "使用产品 A\n";
    }
};

// 具体产品 B
class ConcreteProductB : public Product {
public:
    void use() override {
        std::cout << "使用产品 B\n";
    }
};

// 工厂接口
class Factory {
public:
    virtual ~Factory() = default;
    // 工厂方法:返回一个产品对象
    virtual std::unique_ptr<Product> createProduct() = 0;
};

// 具体工厂 A
class ConcreteFactoryA : public Factory {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductA>();
    }
};

// --- 使用示例 ---
int main() {
    // 创建工厂 A
    ConcreteFactoryA factoryA;
    
    // 通过工厂创建产品 (客户端不需要知道具体的产品类名)
    auto product = factoryA.createProduct();
    product->use(); // 输出: 使用产品 A

    return 0;
}

3. 观察者模式 (Observer)

作用: 定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。

应用场景: 事件处理系统、MVC 架构中的视图更新、发布-订阅模型

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

// 观察者接口
class Observer {
public:
    virtual ~Observer() = default;
    virtual void update(const std::string& message) = 0;
};

// 被观察者 (主题)
class Subject {
private:
    std::vector<Observer*> observers; // 观察者列表
    std::string state;

public:
    void attach(Observer* o) {
        observers.push_back(o);
    }

    void detach(Observer* o) {
        observers.erase(
            std::remove(observers.begin(), observers.end(), o),
            observers.end()
        );
    }

    // 状态改变,通知所有观察者
    void setState(const std::string& s) {
        state = s;
        notify();
    }

    void notify() {
        for (auto* obs : observers) {
            obs->update(state);
        }
    }
};

// 具体观察者
class ConcreteObserver : public Observer {
private:
    std::string name;
public:
    ConcreteObserver(const std::string& n) : name(n) {}

    void update(const std::string& message) override {
        std::cout << name << " 收到通知: " << message << std::endl;
    }
};

// --- 使用示例 ---
int main() {
    Subject weatherStation; // 气象站
    ConcreteObserver user1("用户A");
    ConcreteObserver user2("用户B");

    // 用户订阅气象站
    weatherStation.attach(&user1);
    weatherStation.attach(&user2);

    // 气象站发布消息,所有订阅者收到
    weatherStation.setState("今天天气晴朗");

    // 输出:
    // 用户A 收到通知: 今天天气晴朗
    // 用户B 收到通知: 今天天气晴朗

    return 0;
}

4. 策略模式 (Strategy)

作用: 将算法封装在独立的类中,使它们可以互相替换。客户端可以在运行时选择不同的策略。

应用场景: 支付方式的选择(微信、支付宝)、排序算法的切换。它有助于消除大量的 if-elseswitch 判断。

组合技: 常与工厂模式结合使用,由工厂负责创建具体的策略对象

代码举例:

cpp 复制代码
#include <iostream>
#include <memory>

// 抽象策略类:所有的收费算法都要实现这个接口
class CashStrategy {
public:
    virtual ~CashStrategy() = default;
    // 计算实际收费的接口
    virtual double calculate(double money) = 0;
};

// 具体策略 A:正常收费
class CashNormal : public CashStrategy {
public:
    double calculate(double money) override {
        return money; // 原价返回
    }
};

// 具体策略 B:打折扣
class CashRebate : public CashStrategy {
private:
    double discount; // 折扣率,如 0.8
public:
    CashRebate(double d) : discount(d) {}
    
    double calculate(double money) override {
        return money * discount;
    }
};

// 具体策略 C:满减
class CashReturn : public CashStrategy {
private:
    double condition; // 满足条件,如 300
    double ret;         // 返还金额,如 100
public:
    CashReturn(double c, double r) : condition(c), ret(r) {}
    
    double calculate(double money) override {
        if (money >= condition) {
            return money - ret;
        }
        return money;
    }
};
cpp 复制代码
// 上下文类:负责和具体的策略类交互
class CashContext {
private:
    std::unique_ptr<CashStrategy> strategy; // 持有一个策略对象

public:
    // 构造时注入具体的策略
    CashContext(std::unique_ptr<CashStrategy> s) : strategy(std::move(s)) {}

    // 执行计算
    double getResult(double money) {
        return strategy->calculate(money);
    }
};
cpp 复制代码
int main() {
    // 场景1:正常收费
    CashContext normalContext(std::make_unique<CashNormal>());
    std::cout << "正常收费: " << normalContext.getResult(100) << std::endl;

    // 场景2:打八折
    CashContext rebateContext(std::make_unique<CashRebate>(0.8));
    std::cout << "打八折: " << rebateContext.getResult(100) << std::endl;

    // 场景3:满300减100
    CashContext returnContext(std::make_unique<CashReturn>(300, 100));
    std::cout << "满300减100: " << returnContext.getResult(400) << std::endl;

    return 0;
}

5. 装饰器模式 (Decorator)

作用: 动态地给对象添加额外的职责。相比继承,它提供了一种更灵活的扩展功能的方式。

应用场景: I/O 流处理、给游戏角色动态添加装备属性、网络请求的包装(如添加日志、压缩)

代码举例:

cpp 复制代码
#include <iostream>
#include <memory>

// 组件接口
class Coffee {
public:
    virtual ~Coffee() = default;
    virtual double cost() = 0;
    virtual std::string getDescription() = 0;
};

// 具体组件:基础咖啡
class SimpleCoffee : public Coffee {
public:
    double cost() override { return 2.0; }
    std::string getDescription() override { return "普通咖啡"; }
};

// 装饰器基类 (也是 Coffee 的子类)
class CoffeeDecorator : public Coffee {
protected:
    std::unique_ptr<Coffee> decoratedCoffee;
public:
    CoffeeDecorator(std::unique_ptr<Coffee> coffee) 
        : decoratedCoffee(std::move(coffee)) {}
};

// 具体装饰器:加牛奶
class MilkDecorator : public CoffeeDecorator {
public:
    MilkDecorator(std::unique_ptr<Coffee> coffee) 
        : CoffeeDecorator(std::move(coffee)) {}

    double cost() override {
        return decoratedCoffee->cost() + 0.5; // 基础价格 + 0.5
    }

    std::string getDescription() override {
        return decoratedCoffee->getDescription() + " + 牛奶";
    }
};

// 具体装饰器:加糖
class SugarDecorator : public CoffeeDecorator {
public:
    SugarDecorator(std::unique_ptr<Coffee> coffee) 
        : CoffeeDecorator(std::move(coffee)) {}

    double cost() override {
        return decoratedCoffee->cost() + 0.2;
    }

    std::string getDescription() override {
        return decoratedCoffee->getDescription() + " + 糖";
    }
};

// --- 使用示例 ---
int main() {
    // 点一杯加牛奶和糖的咖啡
    auto myCoffee = std::make_unique<MilkDecorator>(
                        std::make_unique<SugarDecorator>(
                            std::make_unique<SimpleCoffee>()
                        )
                    );

    std::cout << myCoffee->getDescription() << std::endl; // 普通咖啡 + 糖 + 牛奶
    std::cout << "总价: $" << myCoffee->cost() << std::endl; // 2.0 + 0.2 + 0.5 = 2.7

    return 0;
}
相关推荐
fpcc3 小时前
并行编程实战——CUDA编程的并行前缀和
c++·cuda
maplewen.3 小时前
C++11 返回值优化
开发语言·c++·面试
sTone873753 小时前
std::functional 使用场景
c++
hetao17338373 小时前
2026-02-09~02-12 hetao1733837 的刷题记录
c++·算法
ADDDDDD_Trouvaille3 小时前
2026.2.12——OJ72-74题
c++·算法
梵刹古音4 小时前
【C++】函数重写
开发语言·c++
Titan20244 小时前
C++异常学习笔记
c++·笔记·学习
柒儿吖4 小时前
DDlog 高性能异步日志库在 OpenHarmony 的 lycium 适配与分步测试
c++·c#·openharmony
民国二十三画生4 小时前
C++(兼容 C 语言) 的标准输入语法,用来读取一行文本
c语言·开发语言·c++