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

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

相关推荐
ZK_H20 小时前
MFC程序开发自学笔记其一——windows应用程序与c++基础
c++·笔记·mfc
cpp_250120 小时前
P10722 [GESP202406 六级] 二叉树
数据结构·c++·算法·题解·洛谷·树形结构·gesp六级
不负岁月无痕21 小时前
STL-- C++ stack_queue _priority_queue类 模拟实现
开发语言·c++
selt79121 小时前
Redisson 源码深度分析
java·c++·redis·lua
周末也要写八哥21 小时前
浅谈:C++中cpp 14 ~ cpp 17
开发语言·c++·算法
不会C语言的男孩21 小时前
C++ Primer 第13章:拷贝控制
开发语言·c++
c2385621 小时前
map和set
数据结构·c++
basketball61621 小时前
C++进阶:3. unique_ptr 现代C++内存管理的基石
java·jvm·c++
FFZero121 小时前
[mpv脚本系统] (三) C 函数如何注册成 Lua 模块
c++·音视频·lua
我不是懒洋洋21 小时前
从零实现一个Redis客户端:RESP协议与网络编程
开发语言·c++