重温设计模式--原型模式

文章目录

  • 原型模式定义
  • 原型模式UML图
  • 优点
  • 缺点
  • 使用场景
  • C++ 代码示例
  • 深拷贝、浅拷贝

原型模式定义

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象;
核心中的核心就是 克隆clone ,后面讲
原型模式是一种创建型设计模式,它的主要意图是通过复制现有的对象实例来创建新的对象,而不是通过传统的使用构造函数来初始化创建。

原型模式UML图

在这里插入图片描述

优点

提高创建对象的效率:当创建一个对象的过程比较复杂,例如需要进行大量的初始化操作、读取配置文件等,如果采用传统的构造方式每次创建都要重复这些复杂过程,而原型模式通过复制已有对象,能快速创建新对象,节省时间和资源。
便于动态创建对象:可以在运行时根据已有对象动态生成新的对象,对于一些需要根据不同场景灵活生成相似对象的情况非常有用。

缺点

深拷贝和浅拷贝问题:在实现对象复制时,如果对象中包含指针等复杂成员,需要正确处理深拷贝和浅拷贝的情况,否则可能导致数据不一致等问题。比如浅拷贝只是简单复制指针,多个对象会指向同一块内存区域,修改一个对象的数据可能意外影响到其他对象。
每一个类都要配备克隆方法:要使用原型模式,需要在具体的类中实现克隆(复制)的相关方法,增加了代码编写和维护的工作量。

使用场景

对象创建成本高的情况:比如创建一个数据库连接对象,初始化过程涉及到加载驱动、配置参数、建立网络连接等复杂操作,后续需要多个相似的连接对象时,就可以用原型模式复制已有的连接对象来快速创建新的。
根据已有对象生成变体对象:例如在图形绘制系统中,已经绘制了一个圆形,要基于这个圆形生成几个大小、颜色等属性稍有不同的新圆形,通过原型模式复制已有圆形对象再进行属性修改就很方便。

C++ 代码示例

以下是一个简单的 C++ 代码示例来演示原型模式,这里假设有一个简单的 Shape(图形)类作为基类,有 Rectangle(矩形)类继承自它,通过原型模式来复制矩形对象:

#include <iostream>
#include <string>

// 抽象基类,定义克隆接口
class Shape
{
public:
	virtual Shape* clone() = 0;
	virtual void draw() = 0;
	virtual ~Shape() {}
};

// 具体的矩形类
class Rectangle : public Shape
{
private:
	int width;
	int height;
public:
	Rectangle(int w, int h) : width(w), height(h) {}

	// 实现克隆方法,返回一个新的矩形对象副本
	Shape* clone() override 
	{
		return new Rectangle(*this);
	}

	void draw() override
	{
		std::cout << "Drawing a rectangle with width: " << width << " and height: " << height << std::endl;
	}
};

int main() 
{
	Rectangle originalRect(10, 20);
	originalRect.draw();

	// 通过原型模式复制矩形对象
	Shape* clonedRect = originalRect.clone();
	clonedRect->draw();

	delete clonedRect;
	char t;
	std::cin>>t;
	return 0;
}

在这里插入图片描述

在上述代码中:
首先定义了抽象基类 Shape,它有一个纯虚函数 clone 用于克隆对象,还有一个纯虚函数 draw 用于绘制图形(这里只是简单输出图形相关信息示意)。
Rectangle 类继承自 Shape,它有自己的成员变量 width 和 height 表示矩形的宽和高,其构造函数用于初始化这两个属性。关键的是实现的 clone 函数,通过 new Rectangle(this) 利用拷贝构造函数创建了一个新的 Rectangle 对象,这个新对象就是原对象的副本,然后返回这个副本的指针(以 Shape 类型返回,体现了多态性)。
在 main 函数中,先创建了一个原始的矩形对象 originalRect 并调用 draw 展示其信息,然后通过原型模式调用 clone 方法复制出一个新的矩形对象 clonedRect,同样调用 draw 展示,最后记得释放动态分配的内存(通过 delete 操作符),避免内存泄漏。
实际应用中,如果类的成员变量有指针等情况,可能还需要更细致地处理拷贝构造函数来确保深拷贝正确执行,避免出现意外的数据共享和修改问题。

深拷贝、浅拷贝

浅拷贝仅复制对象的引用(指针),而深拷贝会创建一个新对象,并复制对象的内容。
同一类型的对象之间可以赋值,使得两个对象的成员变量的值相同,两个对象仍然是独立的两个对象,这种情况被称为浅拷贝.
一般情况下,浅拷贝没有任何副作用,但是当类中有指针,并且指针指向动态分配的内存空间,析构函数做了动态内存释放的处理,会导致内存问题。

class MyClass {
public:
	int* data;

	MyClass(int value) {
		data = new int(value);
	}

	// 浅拷贝构造函数
	MyClass(const MyClass& other) {
		data = other.data; // 浅拷贝,指针复制
	}

	// 析构函数
	~MyClass() {
		delete data;
	}
};

class MyClass {
public:
	int* data;

	MyClass(int value) {
		data = new int(value);
	}

	// 深拷贝构造函数
	MyClass(const MyClass& other) {
		data = new int(*(other.data)); // 深拷贝,复制对象内容
	}

	// 赋值运算符,进行深拷贝
	MyClass& operator=(const MyClass& other) {
		if (this != &other) {
			delete data;
			data = new int(*(other.data)); // 深拷贝
		}
		return *this;
	}

	// 析构函数
	~MyClass() {
		delete data;
	}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/942013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mac iterm2 使用 lrzsz

前言 mac os 终端不支持使用 rz sz 上传下载文件&#xff0c;本文提供解决方法。 mac 上安装 brew install lrzsz两个脚本 注意&#xff1a;/usr/local/bin/iterm2-send-zmodem.sh 中的 sz命令路径要和你mac 上 sz 命令路径一致。 /usr/local/bin/iterm2-recv-zmodem.sh 中…

【基础篇】1. JasperSoft Studio编辑器与报表属性介绍

编辑器介绍 Jaspersoft Studio有一个多选项卡编辑器&#xff0c;其中包括三个标签&#xff1a;设计&#xff0c;源代码和预览。 Design&#xff1a;报表设计页面&#xff0c;可以图形化拖拉组件设计报表&#xff0c;打开报表文件的主页面Source&#xff1a;源代码页码&#xff…

【magic-dash】01:magic-dash创建单页面应用及二次开发

文章目录 一、magic-dash是什么1.1 安装1.2 使用1.2.1 查看内置项目模板1.2.2 生成指定项目模板1.2.3 查看当前magic-dash版本1.2.4 查看命令说明1.2.5 内置模板列表二、创建虚拟环境并安装magic-dash三、magic-dash单页工具应用开发3.1 创建单页面项目3.1.1 使用命令行创建单页…

《Pytorch框架CV开发-从入门到实战》

目录 1.环境部署2.自动梯度计算张量 tensor3.线性回归4.逻辑回归6.人工神经网络的基本概念6.1 感知器6.2 激活函数6.3多层感知器6.4 反向传播算法——前向传播6.5 反向传播算法——反向传播6.6 反向传播算法——训练方法7.Pytorch基础数据集8.手写数字识别人工神经网络训练8.1 …

WebRTC学习二:WebRTC音视频数据采集

系列文章目录 第一篇 基于SRS 的 WebRTC 环境搭建 第二篇 基于SRS 实现RTSP接入与WebRTC播放 第三篇 centos下基于ZLMediaKit 的WebRTC 环境搭建 第四篇 WebRTC 学习一&#xff1a;获取音频和视频设备 第五篇 WebRTC学习二&#xff1a;WebRTC音视频数据采集 文章目录 系列文章…

国自然联合项目|影像组学智能分析理论与关键技术|基金申请·24-12-25

小罗碎碎念 该项目为国自然联合基金项目&#xff0c;执行年限为2019年1月至2022年12月&#xff0c;直接费用为204万元。 项目研究内容包括影像组学分析、智能计算、医疗风险评估等&#xff0c;旨在通过模拟医生诊断过程&#xff0c;推动人工智能在医疗领域的创新。 项目取得了…

怎样配备公共配套设施,才能让啤酒酿造流程高效环保?

今天&#xff0c;天泰邀请大家和我一起走进啤酒厂&#xff0c;了解水、蒸汽、压缩空气和二氧化碳这些基础设施如何助力啤酒生产&#xff0c;实现高效与环保的完美结合。 水 水是啤酒酿造的基础&#xff0c;啤酒厂对水质的要求极高。为了确保水质达标&#xff0c;啤酒厂设有专…

医疗行业 UI 设计系列合集(一):精准定位

在当今数字化时代&#xff0c;医疗行业与信息技术的融合日益紧密&#xff0c;UI 设计在其中扮演着至关重要的角色。精准定位的 UI 设计能够显著提升医疗产品与服务的用户体验&#xff0c;进而对医疗效果和患者满意度产生积极影响。 一、医疗行业 UI 设计的重要性概述 医疗行业…

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——12使用YOLO-Bin

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——12使用YOLO-Bin ​ 根据前面内容&#xff0c;所有的子任务已经基本结束&#xff0c;接下来就是调用转化的bin模型进行最后的逻辑控制了 1 .YOLO的bin使用 ​ 对于yolo其实有个简单的办法&#xff0c;也…

EMC整改

首先我们来从EMC测试项目构成说起&#xff0c;EMC主要包含两大项&#xff1a;EMI&#xff08;干扰&#xff09;和EMS&#xff08;产品抗干扰和敏感度&#xff09;&#xff0c;当然这两大项中又包括许多小项目。 EMI主要测试项&#xff1a; RE&#xff08;产品辐射&#xff0c…

Xcode 16 编译弹窗问题、编译通过无法,编译通过打包等问题汇总

问题1&#xff1a;打包的过程中不断提示 &#xff1a;codesign 想要访问你的钥匙串中的密钥“develop 或者distribution 证书” 解决&#xff1a;打开钥匙串&#xff0c;点击证书---显示简介---信任----改为始终信任 &#xff08;记住 &#xff1a;不能只修改钥匙的显示简介的…

go window安装protoc protoc生成protobuf文件

1. 下载&#xff1a; Releases protocolbuffers/protobuf GitHub 2. 解压缩&#xff1a; 3. 配置环境变量&#xff1a; 选择系统变量->Path -> 新增 解压缩后的bin路径 4. 打印版本&#xff1a; protoc --version 5. 安装protoc-gen-go cmd 下输入安装命令&#xff0…

在【Arduino IDE】中在线下载和离线下载【ESP系列开发板的SDK】

在线下载 打开Arduino IDE&#xff0c;依次点击 文件➔首选项➔其他开发板管理器地址&#xff0c;复制粘贴以下的开发板管理地址&#xff1a; https://arduino.me/packages/esp32.json https://arduino.me/packages/esp8266.json 如下图所示&#xff0c;然后点击确定&#xf…

Arduino PID 控制教程

在控制系统中,控制器在出现错误和干扰的情况下将特定系统的输出校正为目标。最流行的控制器类型是PID ,它是比例、积分和微分的首字母缩写。在以下教程中,我将向您展示如何在项目中使用这种控制器。 什么是PID? 如上所述,PID 是比例、积分和微分的缩写。这种控制器仅用于反…

vue2 升级为 vite 打包

VUE2 中使用 Webpack 打包、开发&#xff0c;每次打包时间太久&#xff0c;尤其是在开发的过程中&#xff0c;本文记录一下 VUE2 升级Vite 步骤。 安装 Vue2 Vite 依赖 dev 依赖 vitejs/plugin-vue2": "^2.3.3 vitejs/plugin-vue2-jsx": "^1.1.1 vite&…

[WASAPI]从Qt MultipleMedia来看WASAPI

[WASAPI] 从Qt MultipleMedia 来看WASAPI 最近在学习有关Windows上的音频驱动相关的知识&#xff0c;在正式开始说WASAPI之前&#xff0c;我想先说一说Qt的Multiple Media&#xff0c;为什么呢&#xff1f;因为Qt的MultipleMedia实际上是WASAPI的一层封装&#xff0c;它在是线…

springboot创建web项目

一、创建项目 二、导入依赖&#xff08;pom.xml&#xff09; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schem…

springboot481基于springboot社区老人健康信息管理系统(论文+源码)_kaic

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统社区老人健康信息管理系统信息管理难度大&#xff0c;容错…

WebAPI编程(第一天,第二天)

WebAPI编程&#xff08;第一天&#xff0c;第二天&#xff09; day01 - Web APIs 1.1. Web API介绍 1.1.1 API的概念1.1.2 Web API的概念1.1.3 API 和 Web API 总结 1.2. DOM 介绍 1.2.1 什么是DOM1.2.2. DOM树 1.3. 获取元素 1.3.1. 根据ID获取1.3.2. 根据标签名获取元素1.3.…

什么是云+边+端?

什么是云边端&#xff1f; 云、边、端三级是现代计算架构中的一种分层模型&#xff0c;它将计算资源和数据处理分布在不同的层级上&#xff0c;以提高效率、降低延迟&#xff0c;并优化资源利用。 云端&#xff08;Cloud&#xff09;&#xff1a; 云端指的是集中式的数据中心…