网站首页 > 基础教程 正文
原型模式概述
原型模式(Prototype)定义:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。
原型模式(Prototype)正是提供了自我复制的功能,就是说新对象的创建可以通过已有对象进行创建。在C++中,拷贝构造函数(Copy Constructor)分成浅层拷贝和深层拷贝,是系统崩溃的根源之一。
原型模式的工作原理是将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程。从工厂方法角度而言,创建新对象的工厂就是原型类自己。软件系统中有些对象的创建过程比较复杂,且有时需要频繁创建,原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的意图所在。
原型模式结构
原型模式的结构包含以下几个角色:
- 抽象原型类(AbstractPrototype):声明克隆clone自身的接口。
- 具体原型类(ConcretePrototype):实现clone接口。
- 客户端(Client):客户端中声明一个抽象原型类,根据客户需求clone具体原型类对象实例。
原型模式UML类图如下:
克隆的方法
(1) 浅拷贝
在浅拷贝中,如果原型对象的成员变量是值类型(如int、 double、 char等基本数据类型),将复制一份给拷贝对象;如果原型对象的成员变量是引用/指针,则将引用/指针指向的地址拷贝一份给拷贝对象,即原型对象和拷贝对象中的成员变量指向同一个地址。
(2) 深拷贝
在深拷贝中,无论原型对象中的成员变量是值类型还是指针/引用类型,都将复制一份给拷贝对象。浅拷贝和深拷贝的区别,如图所示:
代码:
// 原型模式.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
using namespace std;
class AbstractPrototype
{
public:
AbstractPrototype() { strName = ""; }
AbstractPrototype(string name) { strName = name; }
virtual ~AbstractPrototype() {}
virtual AbstractPrototype* clone() = 0;
virtual void ReviseName(string name) { strName = name; }
virtual void GetNameInfo() { cout << strName << endl; }
protected:
string strName;
};
class ConcretePrototypeA : public AbstractPrototype
{
public:
ConcretePrototypeA() {}
ConcretePrototypeA(string name) : AbstractPrototype(name) {}
~ConcretePrototypeA() {}
AbstractPrototype* clone()
{
ConcretePrototypeA* pType = new ConcretePrototypeA();
pType->strName = this->strName;
return pType;
}
};
class ConcretePrototypeB : public AbstractPrototype
{
public:
ConcretePrototypeB() {}
ConcretePrototypeB(string name) : AbstractPrototype(name) {}
~ConcretePrototypeB() {}
AbstractPrototype* clone()
{
ConcretePrototypeB* pType = new ConcretePrototypeB();
pType->strName = this->strName;
return pType;
}
};
int main()
{
//具体A克隆出B
ConcretePrototypeA* pTypeA = new ConcretePrototypeA("ConcretePrototypeA");
ConcretePrototypeB* pTypeB = reinterpret_cast<ConcretePrototypeB*>(pTypeA->clone());
pTypeA->GetNameInfo();
pTypeB->GetNameInfo();
//具体B克隆出A
pTypeB->ReviseName("ConcretePrototypeB");
pTypeA = reinterpret_cast<ConcretePrototypeA*>(pTypeB->clone());
pTypeA->GetNameInfo();
pTypeB->GetNameInfo();
return 0;
}
猜你喜欢
- 2024-10-12 全面剖析 C++ Boost 智能指针!| CSDN 博文精选
- 2024-10-12 如何攻克 C++ 中复杂的类型转换? c++中四种类型转换的方式
- 2024-10-12 C++|由成员函数到运算符重载(类内、类外、友元方式重载)
- 2024-10-12 C++11新特性(49)- 用移动类对象代替拷贝类对象
- 2024-10-12 C++类的默认成员函数 c++类中定义的成员默认访问属性为( )
- 2024-10-12 C++的23种设计模式(上篇-创建型模式)
- 2024-10-12 C++构造函数和析构函数详解 c语言构造函数和析构函数
- 2024-10-12 c++——默认成员函数 c++成员变量默认值
- 2024-10-12 C++|类中实现操作符重载,用操作符代替成员函数名
- 2024-10-12 C++之构造与析构 c++构造类
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)