4

根据维基百科原型模式是:原型模式是在软件开发中使用的创建设计模式,当要创建的对象类型由原型实例确定时,原型实例被克隆以产生新对象。此模式用于:

  1. 避免在客户端应用程序中使用对象创建者的子类,就像抽象工厂模式一样。

  2. 避免以标准方式(例如,使用关键字)创建新对象的内在成本,new因为它对于给定的应用程序来说过于昂贵。


我在 C++ 中看到了这种模式的某些演示代码,它们都使用复制构造函数。任何人都可以解释第二点是如何应用的(通常以及在 C++ 的上下文中),因为我们无论如何都在克隆函数中使用复制构造函数。如果可以在没有复制构造函数的情况下完成,那么示例代码片段会很棒。

4

3 回答 3

2

您可以复制而无需动态分配。例如,这是一个只发生在本地范围内的克隆:

Foo prototype;

void local()
{
    Foo x = prototype; // first copy
    x.mutate();
    Foo y = x;         // another copy
}

从来没有使用过动态分配。

确实,它return new Foo(*this); 也会创建一个副本,但更重要的是对象是动态分配的。就是你的文章所暗示的成本。

于 2012-07-30T10:58:05.153 回答
1

在我用 Java 制作的一个游戏中,我遇到了一个非常符合原型模式的有趣情况。你看,我有这个 Animation 对象,它存储了一个图像容器来翻阅,以及一些其他数据,这些数据跟踪自上一帧渲染以来的时间、它在哪一帧上、动画是否正在运行等.

我发现多个角色使用同一个动画对象会导致问题。如果两个角色共享一个动画,他们会在相互冲突的时间打开和关闭动画。我会让人们用行走动画静止不动,或者用站立动画移动。动画对象的创建既昂贵又耗时,比如创建精灵、设置它们要显示的时间量、创建图像的间隔队列等。

相反,我将 Animation 对象设为原型对象。如果一个动画克隆自己,它会与所有其他动画共享原始帧集合,因为这些动画是不可变的,但构建起来也很昂贵。相反,新对象将共享这个不可变的基础,但拥有自己的关于绘制哪个帧以及何时绘制的信息。

把它想象成投影仪。当它被克隆时,新投影机可能有它自己的信息,比如它是否在运行,它在哪个帧上,等等,但它可能使用与原始投影机相同的胶片。他们不互相绊倒的原因是这部电影是不变的。(而且创建成本很高)

老实说,以这种方式使用原型是实现享元模式的好方法。共享对象的创建成本很高。如果你“克隆”它们,它们将被实例化为新的瞬态,但仍然与它的创建者共享那些昂贵的基础对象。

于 2012-12-21T09:19:28.233 回答
-1

调用内部不使用动态内存的对象的复制构造函数比通过在动态内存中执行任何分配要快得多new。因为动态内存中的分配是一种系统调用。

于 2012-07-30T11:00:18.467 回答