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

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

相关推荐
c2385629 分钟前
《枚举算法 “翻译官”:用 enum class 给 “游游的礼盒” 算分》
c语言·c++·算法
noipp36 分钟前
推荐题目:洛谷 P5843 [SCOI2012] Blinker 的噩梦
c语言·数据结构·c++·算法·游戏·洛谷·luogu
鱼子星_1 小时前
《算 · 法》题目解析篇(1):最近公共祖先问题,线段树,最长回文子序列
c++·算法·动态规划·递归
小白说大模型2 小时前
Python 工程化设计模式:AI 项目中的异步流水线与策略模式实战
人工智能·python·设计模式
计算机内卷的N天3 小时前
CMake与Visual Studio的使用
c++·ide·visual studio
汉克老师3 小时前
GESP2026年3月认证C++七级( 第三部分编程题(1、物流网络))精讲
c++·最短路·gesp7级
鱼子星_3 小时前
【C++】深入剖析list:list及其双向迭代器实现
开发语言·数据结构·c++·笔记·stl·list
tudousisi2223 小时前
P4667 [BalticOI 2011] Switch the Lamp On复盘
c++
江屿风4 小时前
【C++笔记】【二叉搜索树】流食般投喂
开发语言·数据结构·c++·笔记