欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > C++设计模式:原型模式(Prototype)

C++设计模式:原型模式(Prototype)

2025/2/25 18:05:25 来源:https://blog.csdn.net/chenai886/article/details/143917963  浏览:    关键词:C++设计模式:原型模式(Prototype)

通俗易懂地解读原型模式(Prototype Pattern)

什么是原型模式?

原型模式是一种创建型设计模式,它让我们可以通过复制(克隆)一个现有的对象,快速生成一个新的对象,而不需要再次通过类的实例化来创建。

用大白话来说:

如果你已经有一个模子(原型),你就可以用这个模子快速复制出新对象,就像用模型复制黏土雕塑一样。这样,你不需要每次都从零开始重新雕一个。


为什么需要原型模式?
  1. 节省时间和资源
    • 如果对象的创建很复杂(比如需要加载文件、调用外部服务等),直接复制一个现成的对象会快很多。
  2. 动态创建对象
    • 有时候,我们在运行时并不知道需要创建什么类型的对象,使用原型模式可以很灵活地克隆已有的对象。
  3. 避免类的依赖
    • 不需要在代码中直接实例化某个类,只需复制一个已有的实例即可。

举个例子

假如你在一个图形设计软件中设计了一些图形(比如圆形和矩形)。这些图形可能需要很多属性:大小、颜色、边框等。现在你需要快速生成这些图形的副本,而不是每次都手动创建。


原型模式的实现

下面我们通过一个简单的例子,演示如何用 C++ 实现原型模式:
模拟一个图形系统,通过原型模式实现图形(圆形、矩形)的快速复制。


完整代码
#include <iostream>
#include <string>
#include <memory> // 智能指针管理// 抽象原型类
class Shape {
public:virtual ~Shape() = default;// 克隆方法,返回一个复制的对象virtual std::shared_ptr<Shape> clone() const = 0;// 显示图形信息virtual void draw() const = 0;
};// 圆形类
class Circle : public Shape {
public:Circle(double radius) : radius_(radius) {}// 实现克隆方法std::shared_ptr<Shape> clone() const override {return std::make_shared<Circle>(*this); // 使用复制构造函数}// 显示圆形信息void draw() const override {std::cout << "绘制一个圆,半径为:" << radius_ << "\n";}private:double radius_; // 半径
};// 矩形类
class Rectangle : public Shape {
public:Rectangle(double width, double height) : width_(width), height_(height) {}// 实现克隆方法std::shared_ptr<Shape> clone() const override {return std::make_shared<Rectangle>(*this); // 使用复制构造函数}// 显示矩形信息void draw() const override {std::cout << "绘制一个矩形,宽为:" << width_ << ",高为:" << height_ << "\n";}private:double width_;  // 矩形的宽double height_; // 矩形的高
};// 客户端代码
int main() {// 创建一个圆形原型std::shared_ptr<Shape> circlePrototype = std::make_shared<Circle>(10.0);// 创建一个矩形原型std::shared_ptr<Shape> rectanglePrototype = std::make_shared<Rectangle>(20.0, 15.0);// 克隆圆形std::shared_ptr<Shape> clonedCircle = circlePrototype->clone();// 克隆矩形std::shared_ptr<Shape> clonedRectangle = rectanglePrototype->clone();// 显示克隆的图形clonedCircle->draw();    // 输出:绘制一个圆,半径为:10clonedRectangle->draw(); // 输出:绘制一个矩形,宽为:20,高为:15return 0;
}

运行结果

运行以上代码后,将输出以下结果:

绘制一个圆,半径为:10
绘制一个矩形,宽为:20,高为:15

代码逐步解析
  1. Shape 类:

    • 它是一个抽象原型类,定义了一个clone()方法,让所有子类实现复制的逻辑。
    • 同时,draw()方法用来显示图形信息。
  2. CircleRectangle 类:

    • 它们是具体的原型类,继承自Shape
    • 通过实现clone()方法,使用复制构造函数完成克隆操作。
    • draw()方法显示图形的具体属性。
  3. main 函数(客户端):

    • 客户端创建了一些原型对象(圆形和矩形)。
    • 使用这些原型的clone()方法,快速生成新的对象,并通过draw()方法显示它们。

通俗解释代码

  • clone() 就像一个“复印机”,你放进去一个原型对象(比如一个圆形),它会帮你复印出一个一模一样的新对象。
  • 不同的图形类(如圆形、矩形)都有自己的复制逻辑,但客户端只需要调用clone()就可以完成复制,而不需要关心复制细节。
  • 最终,你可以轻松地复制出大量类似的对象,而无需每次手动创建。

原型模式的优缺点
优点
  1. 提高效率:
    • 复制一个现成的对象比重新初始化一个对象快得多,特别是对象初始化代价很高时(比如加载资源或复杂计算)。
  2. 运行时动态创建:
    • 不需要在编译时确定对象类型,运行时可以基于原型创建实例,灵活性更高。
  3. 减少耦合:
    • 客户端只需要调用clone()方法,而无需关心具体对象的创建细节。
缺点
  1. 复杂的深拷贝:
    • 如果对象有嵌套结构(比如对象内部还有对象),需要实现复杂的深拷贝逻辑。
  2. 内存管理复杂:
    • 如果对象包含动态分配的资源,克隆时需要特别注意释放这些资源,否则可能导致内存泄漏。

适用场景
  1. 对象创建成本高:
    • 比如包含大量数据或需要复杂初始化的对象,可以通过克隆快速复制。
  2. 需要创建相似对象:
    • 比如游戏中的各种怪物、道具等,它们的基础属性相同,但某些细节可以在克隆后修改。
  3. 动态决定对象类型:
    • 如果程序在运行时需要根据情况创建对象,可以通过原型模式更灵活地实现。

总结

原型模式是一种非常实用的设计模式,特别是在需要创建大量相似对象或对象创建成本较高的情况下。通过clone()方法,我们可以轻松地复制一个对象,避免了重新初始化的麻烦。在实际开发中,原型模式广泛用于游戏开发、图形处理、文档复制等场景。希望通过这个简单的图形示例,你已经能够理解并掌握这一设计模式!

完整代码块

#include <iostream>
#include <string>
#include <memory> // 用于智能指针管理// 抽象原型类
class Shape {
public:virtual ~Shape() = default;// 克隆方法,返回一个复制的对象virtual std::shared_ptr<Shape> clone() const = 0;// 显示图形信息virtual void draw() const = 0;// 设置名称,用于标识不同对象void setName(const std::string& name) {name_ = name;}// 获取对象名称std::string getName() const {return name_;}private:std::string name_;
};// 圆形类
class Circle : public Shape {
public:Circle(double radius) : radius_(radius) {}// 实现克隆方法std::shared_ptr<Shape> clone() const override {return std::make_shared<Circle>(*this); // 使用复制构造函数}// 显示圆形信息void draw() const override {std::cout << "圆形对象 [" << getName() << "],半径为:" << radius_ << "\n";}private:double radius_; // 半径
};// 矩形类
class Rectangle : public Shape {
public:Rectangle(double width, double height) : width_(width), height_(height) {}// 实现克隆方法std::shared_ptr<Shape> clone() const override {return std::make_shared<Rectangle>(*this); // 使用复制构造函数}// 显示矩形信息void draw() const override {std::cout << "矩形对象 [" << getName() << "],宽为:" << width_ << ",高为:" << height_ << "\n";}private:double width_;  // 矩形的宽double height_; // 矩形的高
};// 客户端代码
int main() {// 创建原始圆形对象std::shared_ptr<Shape> circlePrototype = std::make_shared<Circle>(10.0);circlePrototype->setName("原始圆形");// 创建原始矩形对象std::shared_ptr<Shape> rectanglePrototype = std::make_shared<Rectangle>(20.0, 15.0);rectanglePrototype->setName("原始矩形");// 克隆圆形std::shared_ptr<Shape> clonedCircle = circlePrototype->clone();clonedCircle->setName("拷贝圆形");// 克隆矩形std::shared_ptr<Shape> clonedRectangle = rectanglePrototype->clone();clonedRectangle->setName("拷贝矩形");// 显示原始和克隆的图形std::cout << "=== 原始对象 ===\n";circlePrototype->draw();rectanglePrototype->draw();std::cout << "\n=== 拷贝对象 ===\n";clonedCircle->draw();clonedRectangle->draw();return 0;
}

运行结果

运行以上代码后,输出如下:

=== 原始对象 ===
圆形对象 [原始圆形],半径为:10
矩形对象 [原始矩形],宽为:20,高为:15=== 拷贝对象 ===
圆形对象 [拷贝圆形],半径为:10
矩形对象 [拷贝矩形],宽为:20,高为:15

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词