C++ 【原型模式】

突破编程_C++_设计模式(原型模式) C++ 设计模式:原型模式 阅读详情

简单介绍

原型模式是一种创建型设计模式 | 它使你能够复制已有对象,客户端不需要知道要复制的对象是哪个类的实例,只需通过原型工厂获取该对象的副本。 以后需要更改具体的类或添加新的原型类,客户端代码无需改变,只需修改原型工厂即可 。

基础理解

Q:为什么使用原型模式
A:如果你有一个对象, 并希望生成与其完全相同的一个复制品。如果直接复制:

  1. 对方可能有私有成员变量(你无法访问私有)
  2. 不知道对方的具体类(可能使用父类接口,但我们需要复制的是具体子类)

解决方案

  • 那我们在外部无法克隆,便可以想想在类的内部设置一个通用的克隆接口。对象可以访问同类对象的私有
  • 克隆返回的对象的配置要与预先的配置相同。甚至有时候当构造函数变量很多几十个,克隆可以完全代替子类构造函数

UML 图

原型注册表 (Prototype Registry) 最简单的注册表原型是一个 名称 → 原型的哈希表。
在这里插入图片描述

实现步骤

  1. 创建原型接口, 并在其中声明 克隆方法。 如果你已有类层次结构, 则只需在其所有类中添加该方法即可。
  2. 原型类必须另行定义一个以该类对象为参数的构造函数。如果你需要修改子类,贼需要调用父类构造函数,让父类复制变量与子类保持一致。
  3. 克隆方法通常只有一行代码newConcretePrototype1(*this);每个类都必须显式重写克隆方法并使用自身类名调用 new运算符。
  4. 还可以创建一个原型注册表, 用于存储常用原型。将对子类构造函数的直接调用替换为对原型注册表的调用。
#include <iostream>
#include <string>
#include <unordered_map>

using std::string;

enum Type //枚举类
{
    PROTOTYPE_1 = 0,
    PROTOTYPE_2
};
//抽象原型类
class Prototype
{
protected:
    string prototype_name_;
    float prototype_field_;

public:
    Prototype() {}
    Prototype(string prototype_name)
        : prototype_name_(prototype_name)
    {
    }
    virtual ~Prototype() {}
    virtual Prototype *Clone() const = 0;
    virtual void Method(float prototype_field)
    {
        this->prototype_field_ = prototype_field;
        std::cout << "从 " << prototype_name_ << " 中调用 Method 方法,字段值为:" << prototype_field << std::endl;
    }
};
//具体原型类1
class ConcretePrototype1 : public Prototype
{
private:
    float concrete_prototype_field1_;

public:
    ConcretePrototype1(string prototype_name, float concrete_prototype_field)
        : Prototype(prototype_name), concrete_prototype_field1_(concrete_prototype_field)
    {
    }

    Prototype *Clone() const override
    {
        return new ConcretePrototype1(*this);
    }
};
//具体原型类2
class ConcretePrototype2 : public Prototype
{
private:
    float concrete_prototype_field2_;

public:
    ConcretePrototype2(string prototype_name, float concrete_prototype_field)
        : Prototype(prototype_name), concrete_prototype_field2_(concrete_prototype_field)
    {
    }
    Prototype *Clone() const override
    {
        return new ConcretePrototype2(*this);
    }
};
//原型注册表
class PrototypeFactory
{
private:
    std::unordered_map<Type, Prototype *, std::hash<int>> prototypes_;

public:
    PrototypeFactory()
    {
        prototypes_[Type::PROTOTYPE_1] = new ConcretePrototype1("原型 1", 50.f);
        prototypes_[Type::PROTOTYPE_2] = new ConcretePrototype2("原型 2", 60.f);
    }

    ~PrototypeFactory()
    {
        for (auto it = prototypes_.begin(); it != prototypes_.end(); ++it)
        {
            delete it->second;
        }
        prototypes_.clear();
    }

    Prototype *CreatePrototype(Type type)
    {
        return prototypes_[type]->Clone();
    }
};

void Client(PrototypeFactory &prototype_factory)
{
    std::cout << "创建原型 1\n";

    Prototype *prototype = prototype_factory.CreatePrototype(Type::PROTOTYPE_1);
    prototype->Method(90);
    delete prototype;

    std::cout << "\n";

    std::cout << "创建原型 2\n";

    prototype = prototype_factory.CreatePrototype(Type::PROTOTYPE_2);
    prototype->Method(10);

    delete prototype;
}

int main()
{
    PrototypeFactory *prototype_factory = new PrototypeFactory();
    Client(*prototype_factory);
    delete prototype_factory;

    return 0;
}

应用场景

你需要复制一些对象, 且独立于这些对象所属的具体类,减少耦合

通常出现在代码需要处理第三方代码通过接口传递过来的对象时。 即使不考虑代码耦合的情况, 你的代码也不能依赖这些对象所属的具体类: 可能人家更改了一下,你就崩了。因为你的客户端也需要更改。如我开头所说的一样

子类的区别仅在于其对象的初始化方式, 那么你可以使用该模式来减少子类的数量。

客户端不必根据需求对子类进行实例化, 只需找到合适的原型并对其进行克隆即可。

与其他模式的关系

  • 在许多设计工作的初期都会使用简单工厂模式 (较为简单, 而且可以更方便地通过子类进行定制), 随后演化为使用抽象工厂模式、 原型模式或生成器模式 (更灵活但更加复杂)。

  • 抽象工厂模式通常基于一组简单工厂, 但你也可以使用原型模式来生成这些类的方法。(在工厂类中添加clone 方法,动态地创建具体的工厂类,而不需要使用new 创建)

  • 原型可用于保存命令模式的历史记录。保存历史记录,可以在需要时重新执行或撤销先前执行的命令。

  • 大量使用组合模式和装饰模式的设计通常可从对于原型的使用中获益。 你可以通过该模式来复制复杂结构, 而非从零开始重新构造。

  • 原型并不基于继承, 因此没有继承的缺点。 另一方面, 原型需要对被复制对象进行复杂的初始化。 简单工厂基于继承, 但是它不需要初始化步骤。

  • 有时候原型可以作为备忘录模式的一个简化版本。当对象的状态相对简单,且不需要频繁保存和恢复时,原型模式是一个更简洁的方案。

代码示例

优缺点

优点缺点
你可以克隆对象, 而无需与它们所属的具体类相耦合克隆包含循环引用的复杂对象可能会非常麻烦。
你可以克隆预生成原型, 避免反复运行初始化代码。
你可以更方便地生成复杂对象。
你可以用继承以外的方式来处理复杂对象的不同配置。

如果有错还望指正。有什么建议也可以留言。
你的赞是我的莫大动力。谢谢大家。

参考文档

Qt C++ prototype(原型模式或者克隆模式) prototype.h #pragma once #include #include #include class CProtoTypeBase { public: virtual CProtoTypeBase* clone() = 0; virtual void printAuthor() = 0; virtual void printGroup() = 阅读详情

相关推荐

C++设计模式——Prototype Pattern原型模式

原型模式是一种创建型设计模式,它允许通过克隆已有对象来创建新对象,从而无需调用显式的实例化过程。原型模式的设计,使得它可以创建一个与原型对象相同或类似的新对象,同时又可以减少对象实例化操作产生的性能开销,使得创建对象的操作更加便捷,它减少了大量不必要的重复工作,并提高了系统性能。当创建对象的操作比较复杂和耗时的时候,原型模式则提供了一个更加高效和简单的创建对象的模式,它可以更加快速的创建对象的副本,且不需要依赖对象的某些实例化步骤,它避免了使用传统的new关键字创建对象实例时的复杂构造过程。

程序员与背包客_CoderZ 2212

C++设计模式(10)——原型模式

C++原型模式

伍粟的博客 1708

C++ 原型模式

原型模式(Prototype Pattern)是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,而无需知道任何创建的细节。

青春不老,奋斗不止! 9975

设计模式 - 原型模式

设计模式 - 原型模式

touchingnotyet的博客 366

【C++实战㊷】C++ 原型模式实战:从概念到高效应用

本文聚焦 C++ 原型模式实战,先阐释其通过复制现有对象创建新对象的定义,说明对象创建成本高、需批量建相似对象等适用场景,介绍克隆方法及深浅克隆核心差异。接着讲解浅克隆、深克隆实现及原型管理器设计,分享深克隆递归实现、与工厂模式结合等实战技巧。最后以报表模板克隆系统为例,展示原型模式应用及效率测试,为开发者提供实用参考。

邓邓子的博客 1330

C++设计模式之原型模式

主要介绍了C++设计模式之原型模式,本文讲解了什么是原型模式、为什么要使用原型模式、代码实例等内容,需要的朋友可以参考下

C++ 设计模式之原型模式

实现原型模式需要给【原型对象】声明⼀个克隆⽅法,执⾏该⽅法会创建⼀个当前类的新对象,并将原始对象中的成员变量复制到新⽣成的对象中,⽽不必实例化。如果⼀个对象的创建过程⽐较复杂时(⽐如需要经过⼀系列的计算和资源消耗),那每次创建该对象都需要消耗资源,⽽通过原型模式就可以复制现有的⼀个对象来迅速创建/克隆⼀个新对象,、并且可以通过克隆避免重复初始化⼯作的场景时可以考虑使⽤原型模式,在克隆对象的时候还可以动态地添加或删除原型对象的属性,创造出相似但不完全相同的对象,提⾼了灵活性。,⽽不是从头开始创建。

K1_uestc的博客 1576

Windows中的TLS 1.2启用方法(IIS、C#、.Net framework)

折腾几天了windows中的tls1.2启用方法!特此记录一下 开发背景: 在一个用.net framework 2.0开发的客户端程序里面嵌入功能调用第三方物联网相关接口,服务器上有一个restful接口用于接收第三方上报的数据及处理,最后再调用第三方的物联网相关接口。本机开发环境Windows 10,客户服务器是Windows Server 2008 R2。 第一次写这种物联网相关的接口调用,而且第三方提供的文档比较简单,最基本的报文示例都没。开发环境里面各种摸索一步一个坑,首先在发送HTTP请求前

dl1314ld的博客 1万+

C++设计模式——原型模式(Prototype Pattern)

C++设计模式——原型模式(Prototype Pattern) 微信公众号:幼儿园的学霸 目录 文章目录C++设计模式——原型模式(Prototype Pattern)目录定义代码示例普通指针方式实现智能指针方式实现总结为什么需要原型模式优缺点 定义 Specify the kinds of Objects to create using a prototypical instance, and create new objects by copying this prototype. 用原型实例指

leonardohaig的博客 1636

手把手教你用Simulink搭建DSOGI-PLL模型(附完整代码下载)

本文详细介绍了在Simulink中搭建高鲁棒性DSOGI-PLL模型的完整工程实践指南。针对传统锁相环在非理想电网下的不足,文章深入剖析了双二阶广义积分器锁相环(DSOGI-PLL)的核心原理与优势,并提供了从模块构建、系统组装到参数整定与测试验证的全流程手把手教程,附有完整代码下载,助力工程师应对谐波、电压跌落等复杂电网工况。

weixin_29223603的博客 388

深入解析MTK DRM初始化流程:从KMS模块到组件框架

本文深入解析了联发科(MTK)平台上DRM显示框架的初始化流程。从内核模块加载、Component框架管理依赖,到核心的mtk_drm_bind函数构建KMS对象(CRTC、Plane、Encoder、Connector),最终完成DRM设备注册并创建用户空间接口。文章结合调试经验,为开发者梳理了从驱动启动到屏幕点亮的完整路径与关键排查点。

onion的博客 768

c++原型模式(Prototype Pattern)

每个原型类实现自己的克隆方法,从而确保了对象的正确复制。

qq_57283958的博客 656

PFC中pb模型实战:从胶结参数设置到破坏模拟全流程解析

本文详细解析了PFC软件中平行胶结模型(PB模型)的实战应用全流程。从胶结参数(pb_kn, pb_ks, pb_ten等)的物理意义与精准赋值入手,深入探讨了模型构建、胶结施加以避免初始损伤的技巧,并系统介绍了破坏过程的监测、阈值判定方法以及高级可视化与常见问题诊断。旨在帮助岩土工程与颗粒材料研究者掌握从参数调试到破坏模拟的核心操作,提升数值模拟的准确性与效率。

php55的博客 1075

原型模式(Prototype Pattern) C++

上一节:建造者模式(Builder Pattern)C++ 原型模式(Prototype Pattern)是一种创建型设计模式,其思想是基于一个原型实例创建对象的副本,从而避免新实例创建时的标准方式(如使用new关键字)。在需要创建的对象与原有对象类似或者创建过程较为复杂时,使用原型模式可以更高效地复制对象。假设我们正在开发一个游戏,其中包含大量的怪物。这些怪物分为几种类型,比如“地精”、“龙”等。每种怪物都有自己的属性(如生命值、攻击力等),但同种类型的怪物在初始状态下这些属性是相同的。在游戏中,我们需要

yaoyaohyl的博客 1004

使用 C# 开发海康设备实时视频流的监控与报警系统

本文介绍了如何使用C#结合海康威视SDK(HCNetSDK)开发安防监控系统,涵盖设备登录、视频流获取、报警处理和云台控制等核心功能。内容包括开发环境配置、系统架构设计、关键代码实现(如设备登录、实时视频播放、报警设置)以及用户界面设计。通过Windows Forms/WPF,开发者可构建完整的监控应用,实现设备管理、视频监控、报警响应等功能。系统采用模块化设计,便于扩展和维护,适用于各类安防场景。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1357

Unity之如何实现TTS文本转语音(真人发音)

微软Azure TTS 文本转语音 服务 将文本转换为逼真的语音的语音服务功能 支持个各国语言,各种中文各种方言,支持不同音色男音女音 支持离线和在线版本

TxNet 5481

C++ 设计模式:原型模式(Prototype Pattern)

C++ 设计模式:原型模式(Prototype Pattern)

冀晓武的博客 1552

mybaits-plus通用CRUD详解及代码案例

文章目录mybaitsplus通用CRUD插入操作方法定义测试用例mybaitsplus主键生成策略设置自增主键设置输入主键:UUID:ID_WORKER_STR:ID_WORKER:更新操作根据id更新方法定义:方法步骤根据条件更新方法定义:更新步骤:根据条件更新(可以更新NULL)删除操作根据id删除方法定义:删除步骤:根据 entity 条件删除方法定义:删除步骤:根据ID 批量删除方法定义:删除步骤:查询操作根据id查询方法定义:查询步骤:根据id批量查询方法定义:查询步骤:根据 entity 条件

流楚丶格念的博客 3406

【c++设计模式08】创建型6:原型模式(Prototype Pattern)

原型模式定义了一个原型接口,该接口用于复制现有对象以创建新对象,从而避免了昂贵的构建过程。使用原型模式,我们可以根据现有对象创建新对象,同时保持对象的类型和状态。浅拷贝:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。深拷贝:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。clone明显是深复制,clone出来的对象是是不能去影响原型对象的。

junxuezheng的博客 1582

车辆网络安全ISO/SAE 21434解读(一)概述

ISO/SAE 21434 《道路车辆 网络安全工程》是SAE和ISO共同制定的一项针对道路车辆的网络安全标准,它是一个面向汽车行业全供应链(OEM及各级供应商)的车辆网络安全管理指导文件

xiaoxiabang的博客 8426

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

C++原型模式:Prototype Pattern

当创建给定类的实例的过程很昂贵或很复杂时,就使用原型模式。原型模式的核心思想是,通过拷贝指定的“原型实例(对象)”,创建跟该对象一样的新对象。简单理解就是“克隆指定对象”。这里提到的“原型实例(对象)”,就是被克隆的对象,它的作用就是指定要创建的对象种类。

lichengyang的博客 175

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

大话设计模式——原型模式(C++简历实现)

C++写过拷贝构造函数和赋值运算符重载的应该都会

Ben_OnceMore 953

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C++创建型模式之原型模式

通过原型设计模式,我们可以轻松地复制现有角色,避免了重复的构造代码,并且可以根据需要对克隆的角色进行微调。这种模式在复杂的游戏场景中非常有用,特别是在需要创建多个相似角色时。相似性:原型模式和拷贝构造函数都用于对象的复制,避免了重复的构造代码。不同点:原型模式是一种设计模式,通过clone()方法实现对象复制;拷贝构造函数是 C++ 语言特性,通过实现对象复制。原型模式提供了更灵活的对象复制机制。

捕鲸叉的专栏 2989

原型模式C++

原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制(克隆)现有对象来创建新对象,而不是通过new关键字直接实例化。这种模式适合需要频繁创建相似对象的场景,可以避免重复初始化的开销,同时简化对象创建过程。

melonbo的专栏 569

C++创建型模式-原型模式

参考文献: 【1】

灰太狼的小秘密 1961

我所理解的设计模式(C++实现)——原型模式(Prototype Pattern)

解决的问题: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。这个其实和C++的拷贝构造函数的作用是一致的,实际上就是动态抽取当前对象运行时的状态。 类图结构:      客户(Client)角色:客户类提出创建对象的请求。 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个C#接口或抽象类实现。此角色给出所有的具体原型类所需的接口。在C#中,抽象

十八道胡同的博客专栏 1万+
上一篇: C++ 【生成器模式】
下一篇: 【Effective C++】第三章资源管理
Absorbed__
博客等级 码龄5年 182粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值