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

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

相关推荐
WolfGang00732113 小时前
代码随想录算法训练营Day48 | 108.冗余连接、109.冗余连接II
数据结构·c++·算法
崇山峻岭之间14 小时前
C++ Prime Plus 学习笔记041
c++·笔记·学习
_风华ts14 小时前
虚函数与访问权限
c++
1001101_QIA14 小时前
C++中不能复制只能移动的类型
开发语言·c++
闻缺陷则喜何志丹15 小时前
【组合数学】P9418 [POI 2021/2022 R1] Impreza krasnali|普及+
c++·数学·组合数学
晨曦夜月15 小时前
头文件与目标文件的关系
linux·开发语言·c++
刃神太酷啦15 小时前
C++ list 容器全解析:从构造到模拟实现的深度探索----《Hello C++ Wrold!》(16)--(C/C++)
java·c语言·c++·qt·算法·leetcode·list
有点。16 小时前
C++ ⼀级 2023 年09 ⽉
c++
LXS_35716 小时前
Day 16 C++提高之模板
开发语言·c++·笔记·学习方法
wyw000016 小时前
鸿蒙开发-如何将C++侧接收的PixelMap转换成cv::mat格式
c++·华为·harmonyos