C++设计模式——原型 (克隆)模式

一、什么是原型模式

Prototype模式说简单点,就是提供了一个clone, 通过已存在对象进行新对象创建。clone()实现和具体的实现语言相关,在C++中我们通过拷贝构造函数实现。

那为啥要写clone的接口来实现这个目的呢?直接使用拷贝构造不香么,偶然在知乎中看到陈硕大佬对此的一个回答,觉得豁然开朗。

Prototype 的意义在于,你拿到一个 基类指针 Base* ,它指向某个 派生类 Derived 对象,你想克隆出 Derived对象,但代码中不写出 Derived 的具体类型,因为有很多派生类,这种情况下你用构造函数是搞不定的。type-switch 是 bad smells 。另外,这里考虑 virtual 的性能损失是主次不分,构造对象需要分配内存,这开销比一次虚函数调用大多了。
–陈硕在知乎中的回答

二、代码示例

#include <iostream>
#include <memory>
#include <cassert>
using namespace std;class Prototype
{
public:/// 这里引入NVI模式std::unique_ptr<Prototype> clone(){ return clone_impl();}void noloop() const{ return noloop_impl();}private:virtual std::unique_ptr<Prototype> clone_impl() const = 0;virtual void noloop_impl() const = 0;
public:Prototype() = default;virtual ~Prototype() = default;
protected:Prototype(const Prototype&) = default;Prototype(Prototype&&) = default;Prototype& operator =(const Prototype&) = default;Prototype& operator=(Prototype&&) = default;
};class Derived : public Prototype
{
private:/// 本质实现还是通过拷贝构造函数,在本例中默认是浅拷贝std::unique_ptr<Prototype> clone_impl() const{return std::make_unique<Derived>(*this);}void noloop_impl() const{ cout << __FUNCTION__ << endl;}
};int main()
{std::unique_ptr<Prototype> p0 = std::make_unique<Derived>();std::unique_ptr<Prototype> p1 = p0->clone();p1->noloop();assert((typeid(*p0) == typeid(*p1)) && (typeid(*p1) == typeid(Derived)));/// 从结果可以看出,p0和p1指向的均为Derived类型对象return 0;
}

在这里插入图片描述

三、总结

Prototype模式的结构和实现都很简单,其关键就是(C++中)拷贝构造函数的实现方
式,这也是C++实现技术层面上的事情。由于在示例代码中不涉及到深层拷贝(主要指有指针、复合对象的情况),因此我们通过编译器提供的默认的拷贝构造函数(按位拷贝)的方式进行实现。说明的是这一切只是为了实现简单起见,也因为本篇的重点不在拷贝构造函数的实现技术,而在Prototype模式本身的思想。

Prototype模式通过复制原型(Prototype)而获得新对象创建的功能,这里Prototype本身就是“对象工厂”(因为能够生产对象),实际上Prototype模式和Builder模式、AbstractFactory模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象),它们之间的区别是:Builder模式重点在对复杂对象的一步步创建(并不直接返回对象),AbstractFactory模式重在产生多个相互依赖类的对象,而Prototype模式重在从自身复制自己创建新类。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

金融网站的技术 SEO:提示和最佳实践

如果你想提高排名&#xff0c;你必须提供高质量的材料&#xff0c;保持你的网站平稳运行&#xff0c;并吸引来自权威网站的联系。但是&#xff0c;作为金融服务供应商&#xff0c;您可能会期望网站访问者和搜索引擎进行更多审查。请记住&#xff0c;你是在要求人们把钱投入你身…

SpringCloudAlibaba之Nacos——详细讲解

目录 一、SpringCloudAlibaba简介 1. spring cloud alibaba 特点 2.springcloud 组件 二、环境搭建 1.构建项目并引入依赖 三、Nacos 1.什么是Nacos 2.安装Nacos 3.启动安装服务 4.访问nacos的web服务管理界面 四、开发服务注册到nacos 1.创建项目并引入依赖 2.配置注册地…

【JavaEE初阶】volatile 关键字、wait 和 notify

目录 一、volatile 关键字 1、volatile 能保证内存可见性 2、volatile 不保证原子性 二、wait 和 notify 1、wait()方法 2、notify()方法 3、notifyAll()方法 4、wait 和 sleep 的对比 一、volatile 关键字 1、volatile 能保证内存可见性 我们前面的线程安全文章中&…

Leetcode394. 字符串解码

Every day a Leetcode 题目来源&#xff1a;394. 字符串解码 解法1&#xff1a;栈 本题中可能出现括号嵌套的情况&#xff0c;比如 2[a2[bc]]&#xff0c;这种情况下我们可以先转化成 2[abcbc]&#xff0c;在转化成 abcbcabcbc。我们可以把字母、数字和括号看成是独立的 TO…

vs配置64位汇编

vs开发64位程序无法使用内联汇编&#xff0c;需要将汇编放到一个单独文件中编译链接。 步骤如下&#xff1a; 生成汇编代码。以asm.asm为例&#xff0c;以下是模板&#xff1a; ;64位汇编程序模板 (Template) ;声明一个ExitProcess函数 ExitProcess PROTO.data;在这里声明变量…

关于pyqt5与moviepy到打包的坑点

1,pyqt5 关于pyqt5 designer.exe 的使用主要就是了解pyqt5右侧菜单栏的功能使用 打包后的文件&#xff0c;需要继承改类&#xff0c;进行图形指令交互 关于pyqt5&#xff0c;要了解信号&#xff0c;和槽点的相互关系。 我在pyqt5中使用moviepy的时候&#xff0c;需要用到异步…

行测空间展开图类型题目通法

国考《行测》空间展开图类型题目通法 摘要 本文介绍一种判断哪一种立体图形可以由空间展开图组成的通用方法。 方法 1.将给定的展开图重构为容易识别的上边一个方块&#xff0c;下边一个方块&#xff0c;中间一个方块条的形式。 姑且称之为十字形吧。 之所以重构成这种形…

WordPress批量上传文章和自动发布文章的方法

专业介绍&#xff1a;WordPress批量上传文章技术解析 在现代数字时代&#xff0c;内容创作是网络存在的驱动力之一。对于博客作者、新闻编辑和内容管理员而言&#xff0c;高效地批量上传文章至WordPress平台是提高工作效率的一个关键方面。WordPress作为最受欢迎的内容管理系统…

能耗远程在线监测系统在工业节能提高效率

摘要&#xff1a;为保证企业实现节能减排目标&#xff0c;设计和使用远程在线监测系统势在必行。远程在线监测系统是基于传感器与网络技术的优势&#xff0c;在企业区域各个位置针对性安装传感器&#xff0c;对实时数据进行采集、编码传输到远程管理系统。远程管理系统对采集的…

Java核心知识点整理大全24-笔记

22. 数据结构 22.1.1. 栈&#xff08;stack&#xff09; 栈&#xff08;stack&#xff09;是限制插入和删除只能在一个位置上进行的表&#xff0c;该位置是表的末端&#xff0c;叫做栈顶 &#xff08;top&#xff09;。它是后进先出&#xff08;LIFO&#xff09;的。对栈的基…

Docker Swarm总结+CI/CD Devops、gitlab、sonarqube以及harbor的安装集成配置(3/5)

博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码下载地址&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb;…

Windows系统搭建Appium 2 和 Appium Inspector 环境

前言 自 2022 年 1 月 1 日起&#xff0c;Appium 核心团队不再维护 Appium 1.x。官方支持的平台驱动程序的所有最新版本均不兼容 Appium 1.x&#xff0c;需要 Appium 2 才能运行。 Appium 2是一个自动化移动应用程序的开源工具&#xff0c;它带来了以下重要改进&#xff1a;  …