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

news2024/12/26 20:16:11

文章目录

  • 原型模式定义
  • 原型模式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;
	}
};

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kibana8.17.0在mac上的安装

1、Kibana是什么 Kibana是与elasticsearch配套使用的数据分析与可视化工具&#xff0c;通过Kibana可以轻松与es中存储的数据进行高效的交互&#xff0c;包括数据写入、检索、删除等操作&#xff0c;并可以通过编写部分代码将数据做成各种报表&#xff0c;从而进行非常直观的统…

61.基于SpringBoot + Vue实现的前后端分离-在线动漫信息平台(项目+论文)

项目介绍 随着社会互联网技术的快速发展&#xff0c;每个行业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线动漫信息平台当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线动漫信息平台&#xff0c;它彻底…

【python】银行客户流失预测预处理部分,独热编码·标签编码·数据离散化处理·数据筛选·数据分割

数据预处理 通过网盘分享的文件&#xff1a;银行流失预测数据和代码 链接: https://pan.baidu.com/s/1loiB8rMvZArfjJccu4KW6w?pwdpfcs 提取码: pfcs 非数值特征处理 目的&#xff1a;将非数值特征转换为数值型&#xff0c;以便模型能够处理。方法&#xff1a; 地理位置&am…

从零开始使用MaxKB打造本地大语言模型智能问答系统与远程交互

文章目录 前言1. 下载运行Ollama2. 安装大语言模型3. 安装Cpolar工具4. 配置公网地址5. 固定公网地址6. MaxKB 添加Olama7.创建问答应用 前言 目前大语言模型&#xff08;LLM&#xff09;已经成为了人工智能领域的一颗璀璨明星&#xff0c;从自然语言处理到智能问答系统&#…

neo4j无法导入csv文件

文章目录 问题解决方案1. 检查Neo4j的neo4j.conf配置文件2. 确保文件路径正确3. 将CSV文件放置到import目录4. 重启Neo4j服务器 问题 neo4j browser中导入csv文件报错无法导入 具体&#xff1a;输入下列语句LOAD CSV WITH HEADERS FROM “file:///D:/KG/relation.csv” AS lin…

WebLogic T3反序列化漏洞(CVE-2018-2628)--vulhub

WebLogic T3反序列化漏洞(CVE-2018-2628) WebLogic在通信过程中使用T3协议传输数据&#xff0c;涉及到了序列化和反序列化操作。 T3协议概述 T3协议是Oracle的私有协议&#xff0c;所以公开的相关资料比较少&#xff0c;这里结合其他师傅的博客简单对T3协议进行一个简要分析…

在瑞芯微RK3588平台上使用RKNN部署YOLOv8Pose模型的C++实战指南

在人工智能和计算机视觉领域,人体姿态估计是一项极具挑战性的任务,它对于理解人类行为、增强人机交互等方面具有重要意义。YOLOv8Pose作为YOLO系列中的新成员,以其高效和准确性在人体姿态估计任务中脱颖而出。本文将详细介绍如何在瑞芯微RK3588平台上,使用RKNN(Rockchip N…

scala借阅图书保存记录(三)

BookDAO package org.app package daoimport models.BookModelimport scala.collection.mutable.ListBuffer//图书&#xff0c;数据操作 class BookDAO {//加载图书&#xff0c;从文件中读入def loadBooks(): ListBuffer[BookModel] {val books new ListBuffer[BookModel]()…

无标记动作捕捉系统如何赋能体育运动分析,推动体育科学发展?

随着技术的不断发展与社会的需要&#xff0c;健康、科学运动成为了大众关注的一个热词。在韩国首尔的中央大学&#xff0c;其生物运动临床康复实验室和运动训练中心就致力于通过生物力学分析来研究与运动相关的伤害&#xff0c;并通过定制科学的训练计划来帮助运动员改进他们的…

Unittest02|TestSuite、TestRunner、HTMLTestRunner、处理excel表数据、邮件接收测试结果

目录 八、测试套件TestSuite和测试运行器TestRunner 1、基本概念 2、创建和使用测试套件 3、 自动发现测试用例、创建测试套件、运行测试 4、生成html的测试报告&#xff1a;HTMLTestRunner 1️⃣导入HTMLTestRunner模块 2️⃣运行测试用例并生成html文件 九、unittest…

[搜广推]王树森推荐系统笔记——曝光过滤 Bloom Filter

曝光过滤 & Bloom Filter 曝光过滤主要在召回阶段做&#xff0c;主要方法是Bloom Filter 曝光过滤问题 -如果用户看过某个物品&#xff0c;则不再把该物品曝光给该用户。 - 原因是重复曝光同一个物品会损害用户体验 - 但长视频通常没有曝光过滤&#xff08;youtube&…

JS CSS HTML 的代码如何快速封装

我们为什么要封装代码&#xff0c;是因为封装后的代码&#xff0c;会显得非常美观&#xff0c;减少代码的复用&#xff0c;方便我们更好的去维护代码&#xff0c;不用一个一个页面的去找去改&#xff0c;直接封装好的代码里面去改就可以了 目录 1.html代码封装 2.CSS代码封装 …

acme ssl证书自动续签 nginx

参考 github 官方操作 &#xff0c;acme操作说明 说下我的操作 安装 acme.sh curl https://get.acme.sh | sh source ~/.bashrc 2.注册 acme.sh --register-account -m 123qq.com 如果你在配置 acme.sh 时选择了其他 CA&#xff08;如 Let’s Encrypt&#xff09;&#xff…

【专题】2024抖音电商母婴行业分析报告汇总PDF洞察(附原数据表)

原文链接&#xff1a;https://tecdat.cn/?p38651 在数字化浪潮的席卷下&#xff0c;抖音电商母婴行业正经历着深刻变革。当下&#xff0c;年轻一代父母崛起&#xff0c;特别是 24 至 30 岁以及 18 至 23 岁的群体成为抖音母婴行业兴趣人群的主力军。他们带来全新育儿理念&…

设计模式之 abstract factory

适用场景 一个系统要独立于它的产品的创建、组合和表示时。一个系统要由多个产品系列中的一个来配置时。当你要强调一系列相关的产品对象的设计以便进行联合使用时。当你提供一个产品类库&#xff0c;而只想显示它们的接口而不是实现时 架构演示 首先client这个东西可以接触到…

UE5仿漫威争锋灵蝶冲刺技能

这两天玩了一下漫威争锋Marvel Rivals&#xff0c;发现是UE5做的&#xff0c;对里面一些角色技能挺感兴趣的&#xff0c;想简单复刻一下技能功能&#xff0c;顺便复习一下学过的知识 首先把摄像机设置调整一下 CameraBoom里搜索lag 把摄像机延迟关掉 &#xff0c;这样摄像机就…

尼伽OLED赋能中国移动,打造移动AI数字人透明显示屏

随着人工智能和显示技术的不断进步&#xff0c;中国移动紧跟科技潮流&#xff0c;将移动AI数字人技术与透明屏完美结合&#xff0c;为用户带来了前所未有的智能交互体验。基于中国移动九天大模型生成的数字人小天&#xff0c;便是这一创新技术的典型代表。它不仅能够实现定点播…

goview——vue3+vite——数据大屏配置系统

低代码数据大屏配置系统&#xff1a; 数据来源是可以动态api配置的&#xff1a; 配置上面的api接口后&#xff0c;在数据过滤中进行数据格式的转化。 以上内容&#xff0c;来源于https://gitee.com/dromara/go-view/tree/master-fetch/ 后端代码如下&#xff0c;需要更改…

GitLab安装|备份数据|迁移数据及使用教程

作者&#xff1a; 宋发元 最后更新时间&#xff1a;2024-12-24 GitLab安装及使用教程 官方教程 https://docs.gitlab.com/ee/install/docker.html Docker安装GitLab 宿主机创建容器持久化目录卷 mkdir -p /docker/gitlab/{config,data,logs}拉取GitLab镜像 docker pull gi…

JavaWeb Servlet的反射优化、Dispatcher优化、视图(重定向)优化、方法参数值获取优化

目录 1. 背景2. 实现2.1 pom.xml2.2 FruitController.java2.3 DispatcherServlet.java2.4 applicationContext.xml 3. 测试 1. 背景 前面我们做了Servlet的一个案例。但是存在很多问题&#xff0c;现在我们要做优化&#xff0c;优化的步骤如下&#xff1a; 每个Fruit请求都需…