C++ 设计模式-原型模式

以下是一个使用 C++ 实现的经典原型模式示例,包含测试代码:

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

// 抽象原型类
class Shape {
public:
    virtual ~Shape() = default;
    virtual std::unique_ptr<Shape> clone() const = 0;
    virtual void draw() const = 0;
    virtual void setColor(const std::string& color) = 0;
};

// 具体原型类:圆形
class Circle : public Shape {
    std::string color;
    double radius;
    double x, y;

public:
    Circle(const std::string& color, double radius)
        : color(color), radius(radius), x(0), y(0) {}

    // 拷贝构造函数(用于克隆)
    Circle(const Circle& other) 
        : color(other.color), radius(other.radius), x(other.x), y(other.y) {}

    std::unique_ptr<Shape> clone() const override {
        return std::make_unique<Circle>(*this);
    }

    void draw() const override {
        std::cout << "Drawing Circle at (" << x << ", " << y 
                  << ") with radius " << radius 
                  << " and color " << color << "\n";
    }

    void setPosition(double x, double y) {
        this->x = x;
        this->y = y;
    }

    void setColor(const std::string& color) override {
        this->color = color;
    }
};

// 具体原型类:矩形
class Rectangle : public Shape {
    std::string color;
    double width;
    double height;
    double x, y;

public:
    Rectangle(const std::string& color, double w, double h)
        : color(color), width(w), height(h), x(0), y(0) {}

    Rectangle(const Rectangle& other)
        : color(other.color), width(other.width), height(other.height),
          x(other.x), y(other.y) {}

    std::unique_ptr<Shape> clone() const override {
        return std::make_unique<Rectangle>(*this);
    }

    void draw() const override {
        std::cout << "Drawing Rectangle at (" << x << ", " << y 
                 << ") size " << width << "x" << height
                 << " color " << color << "\n";
    }

    void setPosition(double x, double y) {
        this->x = x;
        this->y = y;
    }

    void setColor(const std::string& color) override {
        this->color = color;
    }
};

// 客户端/测试代码
int main() {
    // 创建原型对象
    Circle circlePrototype("Red", 10.0);
    Rectangle rectanglePrototype("Blue", 20.0, 30.0);

    // 克隆并修改圆形
    auto clonedCircle = circlePrototype.clone();
    clonedCircle->setColor("Green");
    dynamic_cast<Circle*>(clonedCircle.get())->setPosition(5, 5);
    
    // 克隆并修改矩形
    auto clonedRect = rectanglePrototype.clone();
    clonedRect->setColor("Yellow");
    dynamic_cast<Rectangle*>(clonedRect.get())->setPosition(10, 10);

    // 测试输出
    std::cout << "Original Circle:\n";
    circlePrototype.draw();

    std::cout << "\nCloned Circle:\n";
    clonedCircle->draw();

    std::cout << "\nOriginal Rectangle:\n";
    rectanglePrototype.draw();

    std::cout << "\nCloned Rectangle:\n";
    clonedRect->draw();

    // 验证深拷贝
    auto anotherClone = circlePrototype.clone();
    dynamic_cast<Circle*>(anotherClone.get())->setPosition(100, 100);
    
    std::cout << "\nModified clone position:\n";
    anotherClone->draw();
    
    std::cout << "Original circle position remains unchanged:\n";
    circlePrototype.draw();

    return 0;
}

这个示例演示了:

  1. 原型模式结构

    • Shape 是抽象原型接口
    • CircleRectangle 是具体原型类
    • 使用 clone() 方法创建新对象
  2. 关键实现细节

    • 使用拷贝构造函数实现克隆
    • 通过智能指针(unique_ptr)管理对象生命周期
    • 支持深拷贝(所有成员变量都被正确复制)
    • 提供修改方法验证克隆独立性
  3. 测试验证内容

    • 克隆对象的基本功能
    • 修改克隆对象不影响原型
    • 类型正确性(通过 dynamic_cast)
    • 深拷贝的正确性验证

输出结果示例:

复制代码
Original Circle:
Drawing Circle at (0, 0) with radius 10 and color Red

Cloned Circle:
Drawing Circle at (5, 5) with radius 10 and color Green

Original Rectangle:
Drawing Rectangle at (0, 0) size 20x30 color Blue

Cloned Rectangle:
Drawing Rectangle at (10, 10) size 20x30 color Yellow

Modified clone position:
Drawing Circle at (100, 100) with radius 10 and color Red
Original circle position remains unchanged:
Drawing Circle at (0, 0) with radius 10 and color Red

这个示例展示了原型模式的核心思想:通过克隆现有对象来创建新对象,同时保持克隆对象与原型对象的独立性。使用智能指针可以自动管理内存,而通过拷贝构造函数实现的深拷贝确保了对象状态的独立复制。

相关推荐
拾-光22 分钟前
【Git】命令大全:从入门到高手,100 个最常用命令速查(2026 版)
java·大数据·人工智能·git·python·elasticsearch·设计模式
WiChP1 小时前
【V0.1B9】从零开始的2D游戏引擎开发之路
c++·游戏引擎
Peter·Pan爱编程1 小时前
从 struct 到 class:封装与访问控制的真正意义
c++
Hical612 小时前
C++26 反射落地实战
c++·开源
计算机安禾2 小时前
【c++面向对象编程】第22篇:输入输出运算符重载:<< 与 >> 的友元实现
java·前端·c++
北山有鸟2 小时前
解决香橙派没有适配ov13855的3A算法
linux·c++·相机·isp
多加点辣也没关系3 小时前
设计模式-模板方法模式
设计模式·模板方法模式
故事和你913 小时前
洛谷-【图论2-1】树4
开发语言·数据结构·c++·算法·动态规划·图论
故事和你913 小时前
洛谷-【图论2-1】树1
开发语言·数据结构·c++·算法·深度优先·动态规划·图论
不会C语言的男孩3 小时前
C++ SLTL编程
java·开发语言·c++