原型模式
前言
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
当你需要从A的实例得到一份与A内容相同,但是又互不干扰的实例的话,就需要使用原型模式。
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这个其实和C++的拷贝构造函数的作用是相似的(但不相同),实际上就是动态抽取当前对象运行时的状态。
当然有的时候,如果我们并不需要基于现有的对象复制新的对象,或者我们需要的就是一个干净的空对象,那就用工厂模式或者抽象工厂模式。
为什么需要原型模式?
1. 为什么不用new直接新建对象,而要用原型模式?
用new新建对象不能获取当前对象运行时的状态,其次就算new了新对象,在将当前对象的值复制给新对象,效率也不如原型模式高。
2. 为什么不直接使用拷贝构造函数,而要使用原型模式?
原型模式与拷贝构造函数是不同的概念,拷贝构造函数涉及的类是已知的,原型模式涉及的类可以是未知的(基类的拷贝构造函数只能复制得到基类的对象)。
原型模式生成的新对象可能是一个派生类。拷贝构造函数生成的新对象只能是类本身。原型模式是描述了一个通用方法(或概念),它不管是如何实现的,而拷贝构造则是描述了一个具体实现方法。
Derived d;
Base &b = d;
Derived d2(b); // 试图用b所指向的d来复制构造出一个新的d2,但这是不可以的,因为b的类型是Base,而不是Derived。
UML
#include <iostream>
class CBase
{
public:
CBase() {}
virtual ~CBase() {}
virtual CBase* clone()
{
return new CBase(*this);
}
};
class CDerive : public CBase
{
public:
CDerive(int a): m_ia(a) {}
~CDerive() {}
CBase * clone()
{
return new CDerive(*this);
}
int m_ia;
};
int main()
{
CDerive d(8);
CBase &b = d;
CDerive* d2 = dynamic_cast<CDerive*>(b.clone());
std::cout << d2->m_ia << '\n';
delete d2;
return 0;
}