C++中的23种设计模式精讲

这篇具有很好参考价值的文章主要介绍了C++中的23种设计模式精讲。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 单例模式

题目链接为:小明的购物车

C++代码如下,

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class ShoppingCart {
public:
    static ShoppingCart& get_instance() {
        static ShoppingCart instance = ShoppingCart(); //静态变量,类的所有对象共用一个
        return instance;
    }

    vector<string>& get_goods() { 
        return goods;
    }
    
    vector<int>& get_cnt() {
        return cnt;
    }
    
    void show() {
        int n = goods.size();
        for (int i = 0; i < n; ++i) {
            cout << goods[i] << " " << cnt[i] << endl;
        }
        return;
    }
    
private:
    ShoppingCart () {} //构造函数私有化,防止外部直接实例化类的对象
    
    vector<string> goods; 
    vector<int> cnt; 
};

int main() {
    ShoppingCart& shopping_cart = ShoppingCart::get_instance();
    
    string a;
    int b;
    while (cin >> a >> b) {
        shopping_cart.get_goods().emplace_back(a);
        shopping_cart.get_cnt().emplace_back(b);
    }
    
    shopping_cart.show();
    
    return 0;
}

注意要点:

  1. 构造函数私有化,防止外部直接实例化ShoppingCart类的对象。
  2. 静态变量instance,只会被创建一次,故ShoppingCart类的所有对象共用一个instance。又因为变量instance的类型为ShoppingCart,故该类只会存在一个实例化对象。

2 工厂方法模式

题目链接:积木工厂

C++代码如下,

#include <iostream>
#include <vector>

using namespace std;

class Block {
public:
    virtual void produce() = 0;
};

class CircleBlock : public Block {
    void produce() override {
        cout << "Circle Block" << endl;
    }
};

class SquareBlock : public Block {
public:
    void produce() override {
        cout << "Square Block" << endl;
    }
};

class BlockFactory {
public:
    virtual Block* createBlock() = 0;
};

class CircleBlockFactory : public BlockFactory {
public:
    Block* createBlock() override {
        return new CircleBlock();
    }
};

class SquareBlockFactory : public BlockFactory {
public:
    Block* createBlock() override {
        return new SquareBlock();
    }
};

class BlockFactorySystem {
private:
    vector<Block*> blocks;

public:
    void produceBlocks(BlockFactory* factory, int quantity) {
        for (int i = 0; i < quantity; ++i) {
            Block* block = factory->createBlock();
            blocks.emplace_back(block);
            block->produce();
        }
    }
    
    const vector<Block*>& getBlocks() const {
        return blocks;
    } 
    
    ~BlockFactorySystem() {
        for (Block* block : blocks) {
            delete block;
        }
    }
};

int main() {
    BlockFactorySystem factorySystem;
    
    int productionCount;
    cin >> productionCount;
    
    for (int i = 0; i < productionCount; ++i) {
        string blockType;
        int quantity;
        cin >> blockType >> quantity;
        
        if (blockType == "Circle") {
            factorySystem.produceBlocks(new CircleBlockFactory(), quantity);
        } else if (blockType == "Square") {
            factorySystem.produceBlocks(new SquareBlockFactory(), quantity);
        }
    }
    
    return 0;
}

3 抽象工厂模式

题目链接:家具工厂

C++代码如下,

#include <iostream>
#include <string>

using namespace std;

class Chair {
public:
    virtual void showInfo() = 0;
};

class ModernChair : public Chair {
public:
    void showInfo() override {
        cout << "modern chair" << endl;
    }
};

class ClassicalChair : public Chair {
public:
    void showInfo() override {
        cout << "classical chair" << endl;
    }
};

class Sofa {
public:
    virtual void displayInfo() = 0;
};

class ModernSofa : public Sofa {
public:
    void displayInfo() override {
        cout << "modern sofa" << endl;
    }
};

class ClassicalSofa : public Sofa {
public:
    void displayInfo() override {
        cout <<"classical sofa" << endl;
    }
};

class FurnitureFactory {
public:
    virtual Chair* createChair() = 0;
    virtual Sofa* createSofa() = 0;
};

class ModernFurnitureFactory : public FurnitureFactory {
public:
    Chair* createChair() override {
        return new ModernChair();
    }
    
    Sofa* createSofa() override {
        return new ModernSofa();
    }
};

class ClassicalFurnitureFactory : public FurnitureFactory {
public:
    Chair* createChair() override {
        return new ClassicalChair();
    }
    
    Sofa* createSofa() override {
        return new ClassicalSofa();
    }
};

int main() {
    int N;
    cin >> N;
    
    for (int i = 0; i < N; ++i) {
        string furnitureType;
        cin >> furnitureType;
        
        FurnitureFactory* factory = nullptr;
        if (furnitureType == "modern") {
            factory = new ModernFurnitureFactory(); 
        } else if (furnitureType == "classical") {
            factory = new ClassicalFurnitureFactory();
        }
        
        Chair* chair = factory->createChair();
        Sofa* sofa = factory->createSofa();
        
        chair->showInfo();
        sofa->displayInfo();
        
        delete chair;
        delete sofa;
        delete factory;
    }
    
    return 0;
}

4 建造者模式

题目链接为:自行车加工

C++代码如下,

#include <iostream>
#include <string>

using namespace std;

class Bike {
public:
    string frame;
    string tires;
    
    void setFrame(const string& frame) {
        this->frame = frame;
    }
    
    void setTires(const string& tires) {
        this->tires = tires;
    }
    
    friend ostream& operator<<(ostream& os, const Bike& bike) {
        os << bike.frame << " " << bike.tires;
        return os;
    }
};

class BikeBuilder {
public:
    virtual void buildFrame() = 0;
    virtual void buildTires() = 0;
    virtual Bike getResult() = 0;
};

class MountainBikeBuilder : public BikeBuilder {
private:
    Bike bike;
public:
    void buildFrame() override {
        bike.setFrame("Aluminum Frame");
    }
    
    void buildTires() override {
        bike.setTires("Knobby Tires");
    }
    
    Bike getResult() override {
        return bike;
    }
};

class RoadBikeBuilder : public BikeBuilder {
private:
    Bike bike;

public:
    void buildFrame() override {
        bike.setFrame("Carbon Frame");
    }
    
    void buildTires() override {
        bike.setTires("Slim Tires");
    }
    
    Bike getResult() override {
        return bike;
    }
};

class BikeDirector {
public:
    Bike construct(BikeBuilder& builder) {
        builder.buildFrame();
        builder.buildTires();
        return builder.getResult();
    }
};

int main() {
    int N;
    cin >> N;
    
    BikeDirector director;
    
    for (int i = 0; i < N; ++i) {
        string bikeType;
        cin >> bikeType;
        
        BikeBuilder* builder;
        
        if (bikeType == "mountain") {
            builder = new MountainBikeBuilder();
        } else {
            builder = new RoadBikeBuilder();
        }
        
        Bike bike = director.construct(*builder);
        cout << bike << endl;
        
        delete builder;
    }
    
    return 0;
}

5 原型模式

题目链接为:矩阵原型

C++代码如下,

#include <iostream>
#include <string>
#include <vector>

class Prototype {
public:
    virtual Prototype* clone() const = 0;
    virtual std::string getDetails() const = 0;
    virtual ~Prototype() {}
};

class RectanglePrototype : public Prototype {
private:
    std::string color;
    int width;
    int height;

public:
    RectanglePrototype(std::string color, int width, int height) : color(color), width(width), height(height) {}
    
    Prototype* clone() const override {
        return new RectanglePrototype(*this);
    }
    
    std::string getDetails() const override {
        return "Color: " + color + ", Width: " + std::to_string(width) + ", Height: " + std::to_string(height);
    }
};

int main() {
    std::vector<Prototype*> rectangles;
    
    int N;
    std::cin >> N;
    
    for (int i = 0; i < N; ++i) {
        std::string color;
        int width, height;
        
        std::cin >> color >> width >> height;
        
        Prototype* originalRectangle = new RectanglePrototype(color, width, height);
        
        rectangles.emplace_back(originalRectangle);
    }
    
    for (const auto& rectangle : rectangles) {
        Prototype* clonedRectangle = rectangle->clone();
        std::cout << clonedRectangle->getDetails() << std::endl;
        
        delete clonedRectangle;
    }
    
    for (const auto& rectangle : rectangles) {
        delete rectangle;
    }
    
    return 0;
}

6 适配器模式

题目链接为:扩展坞

C++代码如下,

#include <iostream>

class USB {
public:
    virtual void charge() = 0;
};

class TypeC {
public:
    virtual void chargeWithTypeC() = 0;
};

class TypeCAdapter : public USB {
private:
    TypeC* typeC;

public:
    TypeCAdapter(TypeC* typeC) : typeC(typeC) {}
    
    void charge() override {
        typeC->chargeWithTypeC();
    }
};

class NewComputer : public TypeC {
public:
    void chargeWithTypeC() override {
        std::cout << "TypeC" << std::endl;
    }
};

class AdapterCharger : public USB {
public:
    void charge() override {
        std::cout << "USB Adapter" << std::endl;
    }
};

int main() {
    int N;
    std::cin >> N;
    //std::cin.ignore();
    
    for (int i = 0; i < N; ++i) {
        int choice;
        std::cin >> choice;
        
        if (choice == 1) {
            TypeC* newComputer = new NewComputer();
            newComputer->chargeWithTypeC();
            delete newComputer;
        } else if (choice == 2) {
            USB* usbAdapter = new AdapterCharger();
            usbAdapter->charge();
            delete usbAdapter;
        }
    }
       
    return 0;
}

7 代理模式

题目链接为:小明买房子

C++代码如下,

#include <iostream>

//抽象主题
class HomePurchase {
public:
    virtual void requestPurchase(int area) = 0;
};

//真实主题
class HomeBuyer : public HomePurchase {
public:
    void requestPurchase(int area) override {
        std::cout << "YES" << std::endl;
    }
};

//代理类
class HomeAgentProxy : public HomePurchase {
private:
    HomeBuyer homeBuyer;

public:
    void requestPurchase(int area) override {
        if (area > 100) {
            homeBuyer.requestPurchase(area);
        } else {
            std::cout << "NO" << std::endl;
        }
    }
};

int main() {
    HomePurchase* buyerProxy = new HomeAgentProxy();
    
    int n;
    std::cin >> n;
    
    for (int i = 0; i < n; ++i) {
        int area;
        std::cin >> area;
        buyerProxy->requestPurchase(area);
    }
    
    delete buyerProxy;
    
    return 0;
}

8 装饰模式

题目链接为:咖啡加糖

C++代码如下,

#include <iostream>
#include <memory>

//咖啡接口
class Coffee {
public:
    virtual ~Coffee() {}
    virtual void brew() = 0;
};

//具体的黑咖啡类
class BlackCoffee : public Coffee {
public:
    void brew() override {
        std::cout << "Brewing Black Coffee" << std::endl;
    }
};

//具体的拿铁类
class Latte : public Coffee {
public:
    void brew() override {
        std::cout << "Brewing Latte" << std::endl;
    }
};

//装饰者抽象类
class Decorator : public Coffee {
protected:
    std::unique_ptr<Coffee> coffee;

public:
    Decorator(std::unique_ptr<Coffee> coffee) : coffee(std::move(coffee)) {}
    
    void brew() override {
        if (coffee) {
            coffee->brew();
        }
    }
};

//具体的牛奶装饰者类
class MilkDecorator : public Decorator {
public:
    MilkDecorator(std::unique_ptr<Coffee> coffee) : Decorator(std::move(coffee)) {}
    
    void brew() override {
        Decorator::brew();
        std::cout << "Adding Milk" << std::endl;
    }
};

//具体的糖类修饰者类
class SugarDecorator : public Decorator {
public:
    SugarDecorator(std::unique_ptr<Coffee> coffee) : Decorator(std::move(coffee)) {}
    
    void brew() override {
        Decorator::brew();
        std::cout << "Adding Sugar" << std::endl;
    }
};

//客户端代码
int main() {
    int coffeeType, condimentType;
    while (std::cin >> coffeeType >> condimentType) {
        //根据输入制作咖啡
        std::unique_ptr<Coffee> coffee;
        
        if (coffeeType == 1) {
            coffee = std::make_unique<BlackCoffee>();
        } else if (coffeeType == 2) {
            coffee = std::make_unique<Latte>();
        } else {
            std::cout << "Invalid coffee type" << std::endl;
            continue;
        }
        
        //根据输入添加调料
        if (condimentType == 1) {
            coffee = std::make_unique<MilkDecorator>(std::move(coffee));
        } else if (condimentType == 2) {
            coffee = std::make_unique<SugarDecorator>(std::move(coffee));
        } else {
            std::cout << "Invalid condiment type" << std::endl;
            continue;
        }
        
        //输出制作过程
        coffee->brew();
    }
    
    return 0;
}

9 外观模式

题目链接为:电源开关

C++代码如下,

#include <iostream>
#include <vector>

class AirConditioner {
public:
    void turnOff() {
        std::cout << "Air Conditioner is turned off." << std::endl;
    }
};

class DeskLamp {
public:
    void turnOff() {
        std::cout << "Desk Lamp is turned off." << std::endl;
    }
};

class Television {
public:
    void turnOff() {
        std::cout << "Television is turned off." << std::endl;
    }
};

class PowerSwithFacade {
private:
    DeskLamp deskLamp;
    AirConditioner airConditioner;
    Television television;

public:
    PowerSwithFacade() {
        
    }
    
    void turnOffDevice(int deviceCode) {
        switch (deviceCode) {
            case 1:
                airConditioner.turnOff();
                break;
            case 2:
                deskLamp.turnOff();
                break;
            case 3:
                television.turnOff();
                break;
            case 4:
                std::cout << "All devices are off." << std::endl;
                break;
            default:
                std::cout << "Invalid device code." << std::endl;
        }
    } 
};

int main() {
    int n;
    std::cin >> n;
    std::vector<int> input(n);
    
    for (int i = 0; i < n; ++i) {
        std::cin >> input[i];
    }
    
    PowerSwithFacade powerSwitch;
    
    for (int i = 0; i < n; ++i) {
        powerSwitch.turnOffDevice(input[i]);
    }
    
    return 0;
}

10 桥接模式

题目链接为:桥接模式

C++代码如下,

#include <iostream>
#include <sstream>
#include <vector>

//步骤1:创建实现化接口
class TV {
public:
    virtual void turnOn() = 0;
    virtual void turnOff() = 0;
    virtual void switchChannel() = 0;
};

//步骤2:创建具体实现化类
class SonyTV : public TV {
public:
    void turnOn() override {
        std::cout << "Sony TV is ON" << std::endl;
    }
    
    void turnOff() override {
        std::cout << "Sony TV is OFF" << std::endl;
    }
    
    void switchChannel() override {
        std::cout << "Switching Sony TV channel" << std::endl;
    }
};

class TCLTV : public TV {
public:
    void turnOn() override {
        std::cout << "TCL TV is ON" << std::endl;
    }
    
    void turnOff() override {
        std::cout << "TCL TV is OFF" << std::endl;
    }
    
    void switchChannel() override {
        std::cout << "Switching TCL TV channel" << std::endl;
    }
};

//步骤3:创建抽象化接口
class RemoteControl {
protected:
    TV *tv;

public:
    RemoteControl(TV *tv) : tv(tv) {}
    
    virtual void performOperation() = 0;
};

//步骤4:创建扩充抽象化类
class PowerOperation : public RemoteControl {
public:
    PowerOperation(TV *tv) : RemoteControl(tv) {}
    
    void performOperation() override {
        tv->turnOn();
    }
};

class OffOperation : public RemoteControl {
public:
    OffOperation(TV *tv) : RemoteControl(tv) {}
    
    void performOperation() override {
        tv->turnOff();
    }
};

class ChannelSwitchOperation : public RemoteControl {
public:
    ChannelSwitchOperation(TV *tv) : RemoteControl(tv) {}
    
    void performOperation() override {
        tv->switchChannel();
    }
};

//步骤5:客户端代码
int main() {
    int N;
    std::cin >> N;
    //std::cin.ignore();
    
    for (int i = 0; i < N; ++i) {
        int brand, operation;
        std::cin >> brand >> operation;
        
        TV *tv;
        if (brand == 0) {
            tv = new SonyTV();
        } else {
            tv = new TCLTV();
        }
        
        RemoteControl *remoteControl;
        if (operation == 2) {
            remoteControl = new PowerOperation(tv);
        }  else if (operation == 3) {
            remoteControl = new OffOperation(tv);
        } else {
            remoteControl = new ChannelSwitchOperation(tv); 
        }
        
        remoteControl->performOperation();
        
        delete tv;
        delete remoteControl;
    }
    
    return 0;
}

11 组合模式

题目链接为:公司组织架构

C++代码如下,

#include <iostream>
#include <vector>
#include <sstream>

class Component {
public:
    virtual void display(int depth) = 0;
};

class Department : public Component {
private:
    std::string name;
    std::vector<Component*> children;

public:
    Department(const std::string &name) : name(name) {}
    
    void add(Component *component) {
        children.emplace_back(component);
    }
    
    void display(int depth) override {
        std::string indent(depth * 2, ' ');
        std::cout << indent << name << std::endl;
        for (Component *component : children) {
            component->display(depth + 1);
        }
    }
};

class Employee : public Component {
private:
    std::string name;
    
public:
    Employee(const std::string &name) : name(name) {}
    
    void display(int depth) override {
        std::string indent((depth + 1) * 2, ' ');
        std::cout << indent << name << std::endl;
    }
};

class Company {
private:
    std::string name;
    Department *root;

public:
    Company(const std::string& name) : name(name), root(new Department(name)) {}
    
    void add(Component *component) {
        root->add(component);
    }
    
    void display() {
        std::cout << "Company Structure:" << std::endl;
        root->display(0);
    }
};

int main() {
    std::string companyName;
    std::getline(std::cin, companyName);
    
    Company company(companyName);
    
    int n;
    std::cin >> n;
    //std::cin.ignore();
    
    for (int i = 0; i < n; ++i) {
        std::string type, name;
        std::cin >> type;
        std::getline(std::cin >> std::ws, name);
        
        if (type == "D") {
            Department *department = new Department(name);
            company.add(department);
        } else if (type == "E") {
            Employee *employee = new Employee(name);
            company.add(employee);
        }
    }
    
    company.display();
    
    return 0;
}

12 享元模式

题目链接为:图形编辑器

C++代码如下,

#include <iostream>
#include <unordered_map>
#include <sstream>
#include <string>

enum ShapeType {
    CIRCLE, RECTANGLE, TRIANGLE  
};

std::string shapeTypeToString(ShapeType type) {
    switch (type) {
        case CIRCLE:
            return "CIRCLE";
        case RECTANGLE:
            return "RECTANGLE";
        case TRIANGLE:
            return "TRIANGLE";
        default:
            return "UNKNOWN";
    }
}

class Position {
private:
    int x;
    int y;

public:
    Position(int x, int y) : x(x), y(y) {}
    
    int getX() const {
        return x;
    }
    
    int getY() const {
        return y;
    }
};

class Shape {
public:
    virtual void draw(const Position &position) = 0;
    virtual ~Shape() {}
};

class ConcreteShape : public Shape {
private:
    ShapeType shapeType;
    bool isFirstTime;

public:
    ConcreteShape(ShapeType shapeType) : shapeType(shapeType), isFirstTime(true) {}
    
    void draw(const Position &position) override {
        std::cout << shapeTypeToString(shapeType) << (isFirstTime ? " drawn" : " shared") << " at (" << position.getX() << ", " << position.getY() << ")" << std::endl;
    }
    
    void setFirstTime(bool firstTime) {
        isFirstTime = firstTime;
    }
};

class ShapeFactory {
private:
    std::unordered_map<ShapeType, Shape*> shapes;

public:
    Shape* getShape(ShapeType type) {
        if (shapes.find(type) == shapes.end()) {
            shapes[type] = new ConcreteShape(type);
        }
        return shapes[type];
    }
    
    ~ShapeFactory() {
        for (const auto &entry : shapes) {
            delete entry.second;
        }
    }
};

void processCommand(ShapeFactory &factory, const std::string &command);

int main() {
    ShapeFactory factory;
    std::string command;
    
    while (std::getline(std::cin, command)) {
        processCommand(factory, command);
    }
    
    return 0;   
}

void processCommand(ShapeFactory &factory, const std::string &command) {
    std::istringstream iss(command);
    std::string shapeTypeStr;
    int x, y;
    
    iss >> shapeTypeStr >> x >> y;
    
    ShapeType type;
    if (shapeTypeStr == "CIRCLE") {
        type = CIRCLE;
    } else if (shapeTypeStr == "RECTANGLE") {
        type = RECTANGLE;
    } else if (shapeTypeStr == "TRIANGLE") {
        type = TRIANGLE;
    } else {
        std::cerr << "Invalid shape type: " << shapeTypeStr << std::endl;
        return;
    }
    
    Shape *shape = factory.getShape(type);
    shape->draw(Position(x, y));
    dynamic_cast<ConcreteShape*>(shape)->setFirstTime(false);
}

13 观察者模式

题目链接为:时间观察者

C++代码如下,

#include <iostream>
#include <vector>
#include <algorithm>

//观察者接口
class Observer {
public:
    virtual void update(int hour) = 0;
    virtual ~Observer() = default; //添加虚析构函数
};

//主题接口
class Subject {
public:
    virtual void registerObserver(Observer *observer) = 0;
    virtual void removeObserver(Observer *observer) = 0;
    virtual void notifyObservers() = 0;
    virtual ~Subject() = default; //添加虚析构函数
};

//具体主题实现
class Clock : public Subject {
private:
    std::vector<Observer*> observers;
    int hour;

public:
    Clock() : hour(0) {}
    
    void registerObserver(Observer *observer) override {
        observers.emplace_back(observer);
    }
    
    void removeObserver(Observer *observer) override {
        auto it = std::find(observers.begin(), observers.end(), observer);
        if (it != observers.end()) {
            observers.erase(it);
        }
    }
    
    void notifyObservers() override {
        for (Observer *observer : observers) {
            observer->update(hour);
        }
    }
    
    //添加获取观察者的函数
    const std::vector<Observer*>& getObservers() const {
        return observers;
    }
    
    void tick() {
        hour = (hour + 1) % 24; //模拟时间的推移
        notifyObservers();
    }
};

//具体观察者实现
class Student : public Observer {
private:
    std::string name;

public:
    Student(const std::string &name) : name(name) {}
    
    void update(int hour) override {
        std::cout << name << " " << hour << std::endl;
    }
};

int main() {
    //读取学生数量
    int N;
    std::cin >> N;
    
    //创建时钟
    Clock clock;
    
    //注册学生观察者
    for (int i = 0; i < N; ++i) {
        std::string studentName;
        std::cin >> studentName;
        clock.registerObserver(new Student(studentName));
    }
    
    //读取时钟更新次数
    int updates;
    std::cin >> updates;
    
    //模拟时钟每隔一个小时更新一次
    for (int i = 0; i < updates; ++i) {
        clock.tick();
    }
    
    //释放动态分配的观察者对象
    for (Observer *observer : clock.getObservers()) {
        delete observer;
    }
    
    return 0;
}

14 策略模式

题目链接为:超市打折

C++代码如下,

#include <iostream>
#include <vector>
#include <cmath>

//抽象购物优惠策略接口
class DiscountStrategy {
public:
    virtual int applyDiscount(int originalPrice) = 0;
    virtual ~DiscountStrategy() = default; //添加虚析构函数
};

//九折优惠策略
class DiscountStrategy1 : public DiscountStrategy {
public:
    int applyDiscount(int originalPrice) override {
        return static_cast<int>(std::round(originalPrice * 0.9));
    }
};

//满减优惠策略
class DiscountStrategy2 : public DiscountStrategy {
private:
    int thresholds[4] = {100, 150, 200, 300};
    int discounts[4] = {5, 15, 25, 40};

public:
    int applyDiscount(int originalPrice) override {
        for (int i = sizeof(thresholds) / sizeof(thresholds[0]) - 1; i >= 0; --i) {
            if (originalPrice >= thresholds[i]) {
                return originalPrice - discounts[i];
            }
        }
        return originalPrice;
    }
};

//上下文
class DiscountContext {
private:
    DiscountStrategy *discountStrategy;
    
public:
    void setDiscountStrategy(DiscountStrategy *discountStrategy) {
        this->discountStrategy = discountStrategy;
    }
    
    int applyDiscount(int originalPrice) {
        return discountStrategy->applyDiscount(originalPrice);
    }
};

int main() {
    //读取需要计算优惠的次数
    int N;
    std::cin >> N;
    //std::cin.ignore(); //忽略换行符
    
    for (int i = 0; i < N; ++i) {
        //读取商品价格和优惠策略
        int M, strategyType;
        std::cin >> M >> strategyType;
        
        //根据优惠策略设置相应的打折策略
        DiscountStrategy *discountStrategy;
        switch (strategyType) {
            case 1:
                discountStrategy = new DiscountStrategy1();
                break;
            case 2:
                discountStrategy = new DiscountStrategy2();
                break;
            default:
                //处理未知策略类型
                std::cout << "Unknown strategy type" << std::endl;
                return 1;
        }
        
        //设置打折策略 
        DiscountContext context;
        context.setDiscountStrategy(discountStrategy);
        
        //应用打折策略并输出优惠后的价格
        int discountedPrice = context.applyDiscount(M);
        std::cout << discountedPrice << std::endl;
        
        //释放动态分配的打折策略对象
        delete discountStrategy;
    }
    
    return 0;
}

15 命令模式

题目链接为:自助点餐机

C++代码如下,

#include <iostream>
#include <vector>
#include <string>

class DrinkMaker; //前向声明

//命令接口
class Command {
public:
    virtual void execute() = 0;
    virtual ~Command() = default; //添加虚析构函数
};

//具体命令类-点餐命令
class OrderCommand : public Command {
private:
    std::string drinkName;
    DrinkMaker *receiver; //使用前向声明

public:
    OrderCommand(const std::string& drinkName, DrinkMaker* receiver);
    void execute() override;
};

//接收者类-制作饮品
class DrinkMaker {
public:
    void makeDrink(const std::string& drinkName) {
        std::cout << drinkName << " is ready!" << std::endl;
    }
};

//实现OrderCommand的构造函数和execute函数
OrderCommand::OrderCommand(const std::string& drinkName, DrinkMaker* receiver) : drinkName(drinkName), receiver(receiver) {}

void OrderCommand::execute() {
    receiver->makeDrink(drinkName);
}

//调用者类-点餐机
class OrderMachine {
private:
    Command* command;

public:
    void setCommand(Command* command) {
        this->command = command;
    }
    
    void executeOrder() {
        command->execute();
    }
};

int main() {
    //创建接收者和命令对象
    DrinkMaker drinkMaker;
    
    //读取命令数量
    int n;
    std::cin >> n;
    
    while (n--) {
        //读取命令
        std::string drinkName;
        std::cin >> drinkName;
        
        //创建命令对象 
        Command* command = new OrderCommand(drinkName, &drinkMaker);
        
        //执行命令
        OrderMachine orderMachine;
        orderMachine.setCommand(command);
        orderMachine.executeOrder();
        
        //释放动态分配的命令对象
        delete command;
    }
    
    return 0;
}

16 中介者模式

题目链接为:简易聊天室

C++代码如下,

#include <iostream>
#include <vector>
#include <map>
#include <list>

//抽象中介者
class ChatRoomMediator;

//抽象同事类
class ChatUser {
private:
    std::string name;
    ChatRoomMediator* mediator;
    std::list<std::string> receivedMessages;

public:
    ChatUser(const std::string& name, ChatRoomMediator* mediator);
    
    std::string getName() const {
        return name;
    }
    
    void sendMessage(const std::string& message);
    
    virtual void receiveMessage(const std::string& sender, const std::string& message) = 0;
    
    std::list<std::string> getReceivedMessages() const {
        return receivedMessages;
    }

protected:
    void addReceivedMessage(const std::string& message) {
        receivedMessages.push_back(message);
    }
};

//具体同事类
class ConcreteChatUser : public ChatUser {
public:
    ConcreteChatUser(const std::string& name, ChatRoomMediator* mediator);
    
    void receiveMessage(const std::string& sender, const std::string& message) override;
};

//抽象中介者 
class ChatRoomMediator {
public:
    virtual void sendMessage(const std::string& sender, const std::string& message) = 0;
    virtual void addUser(ChatUser* user) = 0;
    virtual std::map<std::string, ChatUser*> getUsers() = 0;
    virtual ~ChatRoomMediator() = default;
};

//具体中介者
class ChatRoomMediatorImpl : public ChatRoomMediator {
private:
    std::map<std::string, ChatUser*> users;
    
public:
    void sendMessage(const std::string& sender, const std::string& message) override {
        for (const auto& userPair : users) {
            if (userPair.first != sender) {
                userPair.second->receiveMessage(sender, message);
            }
        }
    }
    
    void addUser(ChatUser* user) override {
        users[user->getName()] = user;
    }
    
    std::map<std::string, ChatUser*> getUsers() override {
        return users;
    }
};

//实现ChatUser类的成员函数
ChatUser::ChatUser(const std::string& name, ChatRoomMediator* mediator) : name(name), mediator(mediator) {
    mediator->addUser(this);
}

void ChatUser::sendMessage(const std::string& message) {
    mediator->sendMessage(name, message);
}

//实现ConcreteChatUser类的成员函数
ConcreteChatUser::ConcreteChatUser(const std::string& name, ChatRoomMediator* mediator) : ChatUser(name, mediator) {}

void ConcreteChatUser::receiveMessage(const std::string& sender, const std::string& message) {
    std::string receivedMessage = getName() + " received: " + message;
    addReceivedMessage(receivedMessage);
    std::cout << receivedMessage << std::endl;
}  

int main() {
    std::vector<std::string> userNames;
    int N;
    std::cin >> N;
    
    for (int i = 0; i < N; ++i) {
        std::string userName;
        std::cin >> userName;
        userNames.push_back(userName);
    }
    
    ChatRoomMediator* mediator = new ChatRoomMediatorImpl();
    
    //创建用户对象
    for (const auto& userName : userNames) {
        new ConcreteChatUser(userName, mediator);
    }
    
    //发送消息并输出
    std::string sender, message;
    while (std::cin >> sender >> message) {
        ChatUser* user = mediator->getUsers()[sender];
        if (user != nullptr) {
            user->sendMessage(message);
        }
    }
    
    delete mediator; //释放中介者对象
    
    return 0;
}

17 备忘录模式

题目链接为:redo计数器应用

C++代码如下,

#include <iostream>
#include <stack>

//备忘录
class Memento {
private:
    int value;

public:
    Memento(int val) : value(val) {}
    
    int getValue() const {
        return value;        
    }
};

//发起人(Originator)
class Counter {
private:
    int value;
    std::stack<Memento> undoStack;
    std::stack<Memento> redoStack;

public:
    void increment() {
        redoStack = std::stack<Memento>(); //清空resdoStack
        undoStack.push(Memento(value));
        value++;
    }
    
    void decrement() {
        redoStack = std::stack<Memento>(); //清空redoStack
        undoStack.push(Memento(value));
        value--;
    }
    
    void undo() {
        if (!undoStack.empty()) {
            redoStack.push(Memento(value));
            value = undoStack.top().getValue();
            undoStack.pop();
        }
    }
    
    void redo() {
        if (!redoStack.empty()) {
            undoStack.push(Memento(value));
            value = redoStack.top().getValue();
            redoStack.pop();
        }
    }
    
    int getValue() const {
        return value;
    }
};

int main() {
    Counter counter;
    
    //处理计数器应用的输入
    std::string operation;
    while (std::cin >> operation) {
        if (operation == "Increment") {
            counter.increment();
        } else if (operation == "Decrement") {
            counter.decrement();
        } else if (operation == "Undo") {
            counter.undo();
        } else if (operation == "Redo") {
            counter.redo();
        }
        
        //输出当前计数器的值
        std::cout << counter.getValue() << std::endl;
    }
    
    return 0;
}

18 模板方法模式

题目链接为:咖啡馆

C++代码如下,

#include <iostream>
#include <string>
#include <memory>

//抽象类
class CoffeeMakerTemplate {
private:
    std::string coffeeName;

public:
    //构造函数,接受咖啡名称参数
    CoffeeMakerTemplate(const std::string& coffeeName) : coffeeName(coffeeName) {}
    
    //模板方法定义咖啡制作过程
    virtual void makeCoffee() {
        std::cout << "Making " << coffeeName << ":" << std::endl;
        grindCoffeeBeans();
        brewCoffee();
        addCondiments();
        std::cout << std::endl;
    }
    
    //具体步骤的具体实现由子类提供
    virtual void grindCoffeeBeans() = 0;
    virtual void brewCoffee() = 0;
    
    //添加调料的默认实现
    virtual void addCondiments() {
        std::cout << "Adding condiments" << std::endl;
    }
};

//具体的美式咖啡类
class AmericanCoffeeMaker : public CoffeeMakerTemplate {
public:
    //构造函数传递咖啡名称
    AmericanCoffeeMaker() : CoffeeMakerTemplate("American Coffee") {}
    
    void grindCoffeeBeans() override {
        std::cout << "Grinding coffee beans" << std::endl;   
    }
    
    void brewCoffee() override {
        std::cout << "Brewing coffee" << std::endl;
    }
};

//具体的拿铁咖啡类
class LatteCoffeeMaker : public CoffeeMakerTemplate {
public:
    //构造函数传递咖啡名称
    LatteCoffeeMaker() : CoffeeMakerTemplate("Latte") {}
    
    void grindCoffeeBeans() override {
        std::cout << "Grinding coffee beans" << std::endl;
    }
    
    void brewCoffee() override {
        std::cout << "Brewing coffee" << std::endl;
    }
    
    //添加调料的特定实现
    void addCondiments() override {
        std::cout << "Adding milk" << std::endl;
        std::cout << "Adding condiments" << std::endl;
    }
};

int main() {
    std::unique_ptr<CoffeeMakerTemplate> coffeeMaker;
    
    int coffeeType;
    while (std::cin >> coffeeType) {
        if (coffeeType == 1) {
            coffeeMaker = std::make_unique<AmericanCoffeeMaker>();
        } else if (coffeeType == 2) {
            coffeeMaker = std::make_unique<LatteCoffeeMaker>();
        } else {
            std::cout << "Invalid coffee type" << std::endl;
            continue;
        }
        
        //制作咖啡
        coffeeMaker->makeCoffee();
    }
       
    return 0;
}

19 迭代器模式

题目链接为:学生名单

C++代码如下,

#include <iostream>
#include <vector>

//学生类
class Student {
public:
    Student(const std::string& name, const std::string& studentId) : name(name), studentId(studentId) {}
    
    std::string getName() const {
        return name;
    }
    
    std::string getStudentId() const {
        return studentId;
    } 

private:
    std::string name;
    std::string studentId;
};

//可迭代对象接口
class StudentCollection {
public:
    virtual ~StudentCollection() = default;
    
    virtual std::vector<Student>::iterator begin() = 0;
    virtual std::vector<Student>::iterator end() = 0;
};

//具体可迭代对象
class ConcreteStudentCollection : public StudentCollection {
public:
    void addStudent(const Student& student) {
        students.push_back(student);
    }
    
    std::vector<Student>::iterator begin() override {
        return students.begin();
    }
    
    std::vector<Student>::iterator end() override {
        return students.end();
    }

private:
    std::vector<Student> students;
};

int main() {
    int n;
    std::cin >> n;
    
    ConcreteStudentCollection studentCollection;
    
    for (int i = 0; i < n; ++i) {
        std::string name, studentId;
        std::cin >> name >> studentId;
        studentCollection.addStudent(Student(name, studentId));
    }
    
    //使用迭代器遍历学生集合
    for (auto it = studentCollection.begin(); it != studentCollection.end(); ++it) {
        const Student& student = *it;
        std::cout << student.getName() << " " << student.getStudentId() << std::endl;
    }
    
    return 0;
}

20 状态模式

题目链接为:状态模式

C++代码如下,

#include <iostream>
#include <vector>
#include <string>

//状态接口
class State {
public:
    virtual std::string handle() = 0; //处理状态的方法
};

//具体状态类
class OnState : public State {
public:
    std::string handle() override {
        return "Light is ON";
    }
};

class OffState : public State {
public:
    std::string handle() override {
        return "Light is OFF";
    }
};

class BlinkState : public State {
public:
    std::string handle() override {
        return "Light is Blinking";
    }
};

//上下文
class Light {
private:
    State* state; //当前状态

public:
    Light() : state(new OffState()) {} //初始状态为关闭
    
    void setState(State* newState) {
        delete state;
        state = newState;
    }
    
    std::string performOperation() {
        return state->handle();
    }
    
    ~Light() {
        delete state;
    }
};

int main() {
    int n;
    std::cin >> n;
    std::cin.ignore();
    
    Light light;
    
    for (int i = 0; i < n; ++i) {
        std::string command;
        std::getline(std::cin, command);
        
        if (command == "ON") {
            light.setState(new OnState());
        } else if (command == "OFF") {
            light.setState(new OffState());
        } else if (command == "BLINK") {
            light.setState(new BlinkState());
        } else {
            std::cout << "Invalid command: " << command << std::endl;
        }
        
        std::cout << light.performOperation() << std::endl;
    }
    
    return 0;
}

21 责任链模式

题目链接为:请假审批

C++代码如下,

#include <iostream>
#include <sstream>

class LeaveHandler {
public:
    virtual void handleRequest(const std::string& name, int days) = 0;
};

class Supervisor : public LeaveHandler {
private:
    static const int MAX_DAYS_SUPERVISOR_CAN_APPROVE = 3;
    LeaveHandler* nextHandler;

public:
    Supervisor(LeaveHandler* nextHandler) : nextHandler(nextHandler) {}
    
    void handleRequest(const std::string& name, int days) override {
        if (days <= MAX_DAYS_SUPERVISOR_CAN_APPROVE) {
            std::cout << name << " Approved by Supervisor." << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(name, days);
        } else {
            std::cout << name << " Denied by Supervisor." << std::endl;
        }
    }
};

class Manager : public LeaveHandler {
private:
    static const int MAX_DAYS_MANAGER_CAN_APPROVE = 7;
    LeaveHandler* nextHandler;
    
public:
    Manager(LeaveHandler* nextHandler) : nextHandler(nextHandler) {}
    
    void handleRequest(const std::string& name, int days) override {
        if (days <= MAX_DAYS_MANAGER_CAN_APPROVE) {
            std::cout << name << " Approved by Manager." << std::endl;
        } else if (nextHandler != nullptr) {
            nextHandler->handleRequest(name, days);
        } else {
            std::cout << name << " Denied by Manager." << std::endl;
        }
    }
};

class Director : public LeaveHandler {
private:
    static const int MAX_DAYS_DIRECTOR_CAN_APPROVE = 10;
    
public:
    void handleRequest(const std::string& name, int days) override {
        if (days <= MAX_DAYS_DIRECTOR_CAN_APPROVE) {
            std::cout << name << " Approved by Director." << std::endl;
        } else {
            std::cout << name << " Denied by Director." << std::endl; 
        }
    }
};

class LeaveRequest {
private:
    std::string name;
    int days;

public:
    LeaveRequest(const std::string& name, int days) : name(name), days(days) {}
    
    std::string getName() const {
        return name;
    }
    
    int getDays() const {
        return days;
    }
};

int main() {
    int n;
    std::cin >> n;
    std::cin.ignore();
    
    LeaveHandler* director = new Director();
    LeaveHandler* manager = new Manager(director);
    LeaveHandler* supervisor = new Supervisor(manager);
    
    for (int i = 0; i < n; ++i) {
        std::string input;
        std::getline(std::cin, input);
        std::istringstream iss(input);
        
        std::string name;
        int days;
        
        if (iss >> name >> days) {
            LeaveRequest request(name, days);
            supervisor->handleRequest(name, days);
        } else {
            std::cout << "Invalid input" << std::endl;
            return 1;
        }
    }
    
    delete supervisor;
    delete manager;
    delete director;
    
    return 0;
}

22 解释器模式

题目链接为:数学表达式

C++代码如下,

#include <iostream>
#include <sstream>
#include <stack>
#include <vector>
#include <stdexcept>
#include <iterator>
#include <regex>

//抽象表达类
class Expression {
public:
    virtual int interpret() = 0;
    virtual ~Expression() {}
};

//终结符表达式类-数字
class NumberExpression : public Expression {
private:
    int value;

public:
    NumberExpression(int val) : value(val) {}
    
    int interpret() override {
        return value;
    }
};

//非终结符表达式-加法操作
class AddExpression : public Expression {
private:
    Expression* left;
    Expression* right;
    
public:
    AddExpression(Expression* l, Expression* r) : left(l), right(r) {}
    
    int interpret() override {
        return left->interpret() + right->interpret();
    }
};

//非终结符表达式-乘法操作
class MultiplyExpression : public Expression {
private:
    Expression* left;
    Expression* right;

public:
    MultiplyExpression(Expression* l, Expression* r) : left(l), right(r) {}
    
    int interpret() override {
        return left->interpret() * right->interpret();
    }
};

//非终结符表达式-操作符
class OperatorExpression : public Expression {
private:
    std::string oper;

public:
    OperatorExpression(const std::string& op) : oper(op) {}
    
    int interpret() override {
        throw std::runtime_error("OperationExpression does not support interpretaion");
    }
    
    std::string getOperator() const {
        return oper;
    }
};

//解析表达式字符串
int parseExpression(const std::string& expressionStr) {
    std::istringstream iss(expressionStr);
    std::vector<std::string> elements(std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>());
    
    std::stack<Expression*> stack;
    
    for (const auto& element : elements) {
        if (std::regex_match(element, std::regex("\\d+"))) {
            stack.push(new NumberExpression(std::stoi(element)));
        } else if (element == "+" || element == "*") {
            stack.push(new OperatorExpression(element));
        } else {
            throw std::invalid_argument("Invalid element in expression: " + element);
        }
    }
    
    while (stack.size() > 1) {
        Expression* right = stack.top();
        stack.pop();
        Expression* operatorExp = stack.top();
        stack.pop();
        Expression* left = stack.top();
        stack.pop();
        
        if (auto* opExp = dynamic_cast<OperatorExpression*>(operatorExp)) {
            std::string op = opExp->getOperator();
            if (op == "+") {
                stack.push(new AddExpression(left, right));
            } else if (op == "*") {
                stack.push(new MultiplyExpression(left, right));
            }
        } else {
            throw std::invalid_argument("Invalid operator type in expression");
        }
    }
    
    int result = stack.top()->interpret();
    delete stack.top();
    return result;
}

int main() {
    std::vector<std::string> input_lines;
    std::string line;
    
    while (std::getline(std::cin, line) && !line.empty()) {
        input_lines.push_back(line);
    }
    
    for (size_t i = 0; i < input_lines.size(); ++i) {
        try {
            int result = parseExpression(input_lines[i]);
            std::cout << result << std::endl;
        } catch (const std::exception& e) {
            std::cout << "Error - " << e.what() << std::endl;
        } 
    }
    
    return 0;
}

23 访问者模式

题目链接为:图形的面积

C++代码如下,

#include <iostream>
#include <cmath>
#include <vector>

class Shape;

//访问者接口
class Visitor {
public:
    virtual void visit(class Circle& circle) = 0;
    virtual void visit(class Rectangle& rectangle) = 0;
};

//元素接口
class Shape {
public:
    virtual ~Shape() {} //添加虚析构函数
    virtual void accept(Visitor& visitor) = 0;
};

//具体元素类
class Circle : public Shape {
private:
    int radius;
    
public:
    Circle(int radius) : radius(radius) {}
    
    int getRadius() const {
        return radius;
    }
    
    void accept(Visitor& visitor) override;
};

//具体元素类
class Rectangle : public Shape {
private:
    int width;
    int height;

public:
    Rectangle(int width, int height) : width(width), height(height) {}
    
    int getWidth() const {
        return width;
    }
    
    int getHeight() const {
        return height;
    }
    
    void accept(Visitor& visitor) override;
};

//具体访问者类
class AreaCalculator : public Visitor {
public:
    void visit(Circle& circle) override;
    void visit(Rectangle& rectangle) override;
};

//对象结构类
class Drawing {
private:
    std::vector<Shape*> shapes;

public:
    Drawing(const std::vector<Shape*>& shapes) : shapes(shapes) {}
    
    void accept(Visitor& visitor) {
        for (Shape* shape : shapes) {
            shape->accept(visitor);
        }
    }
};

//实现accept函数
void Circle::accept(Visitor& visitor) {
    visitor.visit(*this);
}

void Rectangle::accept(Visitor& visitor) {
    visitor.visit(*this);
}

//实现visit函数
void AreaCalculator::visit(Circle& circle) {
    double area = 3.14 * std::pow(circle.getRadius(), 2);
    std::cout << area << std::endl;
}

void AreaCalculator::visit(Rectangle& rectangle) {
    int area = rectangle.getWidth() * rectangle.getHeight();
    std::cout << area << std::endl;
}

int main() {
    int n;
    std::cin >> n;
    
    std::vector<Shape*> shapes;
    
    for (int i = 0; i < n; ++i) {
        std::string type;
        std::cin >> type;
        
        if (type == "Circle") {
            int radius;
            std::cin >> radius;
            shapes.push_back(new Circle(radius));
        } else if (type == "Rectangle") {
            int width, height;
            std::cin >> width >> height;
            shapes.push_back(new Rectangle(width, height));
        } else {
            //处理无效输入
            std::cout << "Invalid input" << std::endl;
            return 1;
        }
    }
    
    Drawing drawing(shapes);
    AreaCalculator areaCalculator;
    drawing.accept(areaCalculator);
    
    //释放动态分配的内存
    for (Shape* shape : shapes) {
        delete shape;
    }
        
    return 0;
}

参考

卡码网文章来源地址https://www.toymoban.com/news/detail-797412.html

到了这里,关于C++中的23种设计模式精讲的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包