您现在的位置是:首页 > 正文

【C++】设计模式:prototype 原型模式

2023-11-06 15:35:23阅读 11
/*
代码说明:原型模式示例代码
作用说明:原型模式提供了自我复制的功能,就是说新对象的创建可以通过已有的对象进行创建。用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。可以说,拷贝是原型模式的精髓所在。
基本思想:
在找工作的时候,我们需要准备简历,假设没有打印设备,我们需要手写多份简历,这些简历的内容都是一样的,这样有个缺陷,如果想要修改简历中的某项,那么所有已经写好的简历都需要修改,工作量很大.
随着科技的进步,出现了打印设备。我们只需要手写一份,然后利用打印设备复印多份即可。如果要修改简历中的某项,那么修改原始版本就可以,然后再复印。原始的那份手稿相当于一个原型,有了它,通过复印(拷贝)创造出更多的新简历。这就是原型模式的基本思想。
*/

#include<iostream>
using namespace std;

enum imagType
{
	LSAT,SPOT
};//对象的类型

class Image
{
	public:
		virtual void draw() = 0;
		static Image * findAndClone(imagType);//克隆出相应的对象
	protected:
		virtual imagType returnType() = 0;
		virtual Image* clone() = 0;//子类通过重写此函数,以供父类正确的克隆出相应的对象
		static void addPrototype(Image* image)
		{
			_prototypes[_nextSlot++] = image;
		}//子类通过此函数将自己注册到父类中
	private:
		static Image* _prototypes[10];//容量:最多X种对象类型
		static int _nextSlot;
};

Image * Image::_prototypes[]{};
int Image::_nextSlot{0};

Image* Image::findAndClone(imagType type)
{
	for(int i = 0; i < _nextSlot; i++){
		if(_prototypes[i]->returnType() == type){
			return _prototypes[i]->clone();
		}
	}
}//克隆出相应的对象

/*
原型模式的设计精髓之一就是提供了两个构造函数。
1.一种构造函数的类型一定设置为private,在构造时将自己通过父类的addPrototype函数注册到父类中;子类中包含一个自己的static对象,因此编译期间自动构造自己并实现注册。
2.一种构造函数的类型可以设置为protected,为了跟第一种区别,可以设置一个无意义的形参(只设置,不使用),在实际clone的时候调用此构造函数去实现克隆。
*/

class LandSatImage:public Image
{
	public:
		imagType returnType()
		{
			return LSAT;
		}
		void draw()
		{
			cout<<"LandSatImage"<<_id<<endl;
		}
		Image* clone()
		{
			return new LandSatImage(1);
		}
	protected:
		LandSatImage(int dummy)
		{
			_id = _count++;
		}//protected构造函数,实现克隆的时候调用此函数。形参dummy无意义仅用作区分private构造函数。
	private:
		static LandSatImage _landSatImage;//创建一个自己
		
		LandSatImage()
		{
			addPrototype(this);
		}//private构造函数,static对象实例化的时候自动调用此函数
		
		int _id;
		static int _count;
};

LandSatImage LandSatImage::_landSatImage{};
int LandSatImage::_count = 1;//static,自动创建一个对象,因此此处计数为1

class SpotImage:public Image
{
	public:
		imagType returnType()
		{
			return SPOT;
		}
		void draw()
		{
			cout<<"SpotImage::draw"<<_id<<endl;
		}
		Image* clone()
		{
			return new SpotImage(1);
		}
	protected:
		SpotImage(int dummy)
		{
			_id = _count++;
		}
	private:
		SpotImage()
		{
			addPrototype(this);
		}
		
		static SpotImage _spotImage;
		
		int _id;
		static int _count;
};

SpotImage SpotImage::_spotImage{};
int SpotImage::_count = 1;

const int NUM_IMAGES = 8;

imagType input[NUM_IMAGES] = 
{
	LSAT,LSAT,LSAT,SPOT,LSAT,SPOT,SPOT,SPOT
};

int main()
{
	Image* images[NUM_IMAGES];
	for(int i = 0; i < NUM_IMAGES; i++)
	{
		images[i] = Image::findAndClone(input[i]);
	}
	for(int i = 0; i < NUM_IMAGES; i++)
	{
		images[i]->draw();
	}
	for(int i = 0; i < NUM_IMAGES; i++)
	{
		delete images[i];
	}
	return 0;
}
文章来源:https://blog.csdn.net/weixin_43717839/article/details/130986043
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:https://www.dflian.com/953.html

网站文章

  • Vulnhub-drippingblues

    Vulnhub-drippingblues

    不过FTP服务器比较麻烦一些,因为FTP服务器使用了两个连接,分别是命令通道与数据通道。Tcp/ip协议中,FTP标准命令TCP端口号为21,Port方式数据端口为20。Ftp协议的任务是从一台计算机...

    2023-11-06 15:35:19
  • 【Linux】Linux入门学习之常用命令一

    【Linux】Linux入门学习之常用命令一

    Linux的常用命令什么是Linux?有哪些Linux内核的操作系统 ?Linux的目录结构Linux命令使用MobaXterm backup工具

    2023-11-06 15:35:15
  • 指针的初阶

    指针的初阶

    这一次是对指针的初步认识,指针的内容还有一大块需要我们去开掘,小编之后还会继续完善指针的内容,大家一起努力吧!比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四...

    2023-11-06 15:35:10
  • xshell ssh连接linux时提示ssh服务器拒绝了密码

    xshell ssh连接linux时提示ssh服务器拒绝了密码

    xshell ssh连接linux时提示ssh服务器拒绝了密码

    2023-11-06 15:35:07
  • Go 异步任务

    Go 异步任务

    异步任务在开发中很常见,用来做解耦。本文介绍一下异步队列的实现的几个问题,并且结合三方库实现来分析。带着上面的问题,对比https://github.com/golang-queue/queue的实现,说明一下。

    2023-11-06 15:35:00
  • 【web前端】web前端设计入门到实战第一弹——html基础精华

    【web前端】web前端设计入门到实战第一弹——html基础精华

    一:图片属性 二:音频标签 三: 视频标签 四:链接标签 五:列表标签 5.1.无序列表 5.2.有序列表 5.3.自定义列表 六:表格 6.1合并单元格 七:input标签 八:select系列 九: 文本域标签 十:label标签十一:语义化标签 十二:字符实体

    2023-11-06 15:34:57
  • SpringBoot如何自动生成实体类和Dao层以及映射文件

    SpringBoot如何自动生成实体类和Dao层以及映射文件 一、首先添加自动生成代码插件 org.mybatis.generator ...

    2023-11-06 15:34:51
  • Java中的接口和抽象类有什么区别?

    Java中的接口和抽象类有什么区别?

    接口和抽象类是 Java 面向对象设计的两个基础机制。接口是对行为的抽象,它是抽象方法的集合,利用接口可以达到 API 定义和实现分离的目的。接口,不能实例化;不能包含任何非常量成员,任何 field...

    2023-11-06 15:34:45
  • Java的日期与时间java.time.Duration的简介说明

    Java的日期与时间java.time.Duration的简介说明

    2023-11-06 15:34:41
  • WEB编程:期末展示

    WEB编程:期末展示

    期末大作业展示:一、项目要求1、用户可注册登录网站,非注册用户不可登录查看数据2、用户注册、登录、查询等操作记入数据库中的日志3、爬虫数据查询结果列表支持分页和排序4、用Echarts或者D3实现3个...

    2023-11-06 15:34:39