c++如何实现原型模式 c++设计模式之Prototype【实例】


C++原型模式通过抽象基类声明clone()接口,具体类实现深拷贝逻辑,可选原型管理器按名注册与克隆,核心是对象自主克隆以解耦构造细节。

在 C++ 中实现原型模式,核心是让对象能“克隆自己”——通过定义一个统一的克隆接口,并由具体类自行实现深拷贝逻辑,从而避免紧耦合于构造细节,支持运行时动态创建类型未知的对象。

1. 原型基类:定义克隆接口

声明一个抽象基类(如 Prototype),提供纯虚函数 clone()。它不关心怎么复制,只约定“你能复制出一个新对象”。

注意:返回类型通常用智能指针(如 std::unique_ptr)或原始指针,推荐前者以明确所有权。

示例:

class Prototype {
public:
    virtual ~Prototype() = default;
    virtual std::unique_ptr clone() const = 0;
};

2. 具体原型类:实现深拷贝逻辑

每个可被克隆的具体类(如 ConcretePrototypeA)继承基类,重写 clone(),在其中调用自身构造函数或手动复制成员变量。

若含指针、容器、资源句柄等,必须做深拷贝;否则默认拷贝构造可能引发浅拷贝问题(如双释放、悬空指针)。

示例(含动态分配成员):

class ConcretePrototypeA : public Prototype {
private:
    int value_;
    std::string* data_; // 动态分配,需深拷贝

public: ConcretePrototypeA(int v, const std::string& s) : value(v), data(new std::string(s)) {}

// 深拷贝实现
std::unique_ptr clone() const override {
    return std::make_unique(*this);
}

// 自定义拷贝构造(确保深拷贝 data_)
ConcretePrototypeA(const ConcretePrototypeA& other)
    : value_(other.value_), 
      data_(other.data_ ? new std::string(*other.data_) : nullptr) {}

~ConcretePrototypeA() { delete data_; }

};

3. 原型管理器(可选但实用):集中注册与获取

用一个简单注册表(如 std::map<:string std::unique_ptr>>)缓存原型实例,客户端通过字符串 ID 获取并克隆,解耦创建逻辑。

适用于需要按名动态生成多种类型的场景(如配置驱动的对象工厂)。

示例简版:

class PrototypeRegistry {
private:
    std::map> prototypes_;

public: void registerPrototype(const std::string& name, std::uniqueptr proto) { prototypes[name] = std::move(proto); }

std::unique_ptr create(const std::string& name) const {
    auto it = prototypes_.find(name);
    return (it != prototypes_.end()) ? it->second->clone() : nullptr;
}

};

// 使用: PrototypeRegistry registry; registry.registerPrototype("A", std::make_unique(42, "hello")); auto obj = registry.create("A"); // 得到一份独立副本

4. 注意事项与常见坑

原型模式不是万能的,C++ 实现中需特别留意:

  • 拷贝语义必须明确:如果类有自定义析构/赋值/移动操作,拷贝构造函数务必正确实现深拷贝,否则 clone() 会失效
  • 避免裸指针管理:优先用 std::unique_ptrstd::shared_ptr 返回克隆结果,防止内存泄漏或误删
  • const 正确性clone() 声明为 const 成员函数,表示克隆不改变原对象状态
  • 不依赖 RTTI 或反射:C++ 没有内置类型名自动构造,所有原型都需提前注册或硬编码创建

原型模式在 C++ 中本质是“面向对象的拷贝抽象”,它把“怎么造一个新对象”的决策权交给对象自身,适合配置化、插件化或需大量相似对象的系统。不复杂但容易忽略深拷贝细节,写对了就非常稳健。


# 编码  # c++  # 注册表  # red  # String  # 面向对象  # 成员变量  # 成员函数  # 构造函数  # const  # auto  # 字符串  # 指针  # 继承  # 虚函数  # 纯虚函数  # 接口  # 空指针  # map  # 对象  # prototype  # 自定义  # 可选  # 管理器  # 动态分配  # 句柄  # 适用于  # 你能  # 重写  # 它不  # 并由 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: php订单日志权限怎么设_php订单日志文件权限设置技巧【技巧】  Win11讲述人怎么关闭_Win11误触开启语音朗读关闭【快捷键】  如何在 Go 应用中实现自动错误恢复与进程重启机制  如何用正则表达式精确匹配“start”到“end”之间最多含一个换行符的文本段  Windows10系统怎么查看CPU温度_Win10性能监视器查看硬件数据  Python文件操作优化_大文件与流处理解析【教程】  php内存溢出怎么排查_php内存限制调试与优化方法【说明】  Win11怎么解压RAR文件 Win11自带解压功能使用方法  Mac的“调度中心”与“空间”怎么用_Mac多桌面高效管理【技巧】  Win11怎样安装微信开发者工具_Win11安装开发者工具教程【步骤】  Windows 11登录时提示“用户配置文件服务登录失败”怎么办_Windows 11修复损坏的用户配置文件  php能跑在stm32上吗_php在stm32微控制器上的移植方法【介绍】  Win11怎么清理C盘系统错误报告_Win11清理系统错误报告技巧【教程】  如何在Golang中处理二进制数据_Golang io与encoding/binary二进制操作方法  如何在 Go 中正确反序列化 XML 多节点数组(解决仅解析首个元素的问题)  如何在 Go 后端安全获取并验证前端存储的 JWT?  Win11时间怎么同步到原子钟 Win11高精度时间同步设置【指南】  Windows如何查看和管理已安装的字体?(字体文件夹)  php485在php5.6下能用吗_php485旧版本兼容性问题说明【详解】  VSC怎么配置PHP的Xdebug_远程调试设置步骤【详解】  mac怎么安装adb_MAC配置Android ADB开发环境【详解】  c++ std::atomic如何保证原子性 c++ CAS操作原理【底层】  Win11任务栏怎么固定应用 Win11将软件图标固定到底部【步骤】  Mac如何设置动态壁纸?(让桌面动起来)  如何在 Windows 11 中使用 AlomWare 工具箱  c++如何利用doxygen生成开发文档_c++ 代码注释规范与HTML文档导出【案例】  C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)  如何使用Golang匿名函数_快速定义临时函数逻辑  Windows10怎么用“讲述人”读屏辅助 Windows10轻松使用开启讲述人朗读屏幕文字帮助视障用户【教程】  如何在Golang中捕获JSON序列化错误_Golangjson.Marshal错误处理示例  php做exe支持多线程吗_并发处理实现方式【详解】  XSLT怎么生成动态的HTML属性名和标签名  Win11怎么硬盘分区 Win11新建磁盘分区详细教程【步骤】  C#如何使用XPathNavigator高效查询XML  win11 OneDrive怎么彻底关闭 Win11禁用并卸载OneDrive教程【分享】  php485能和物联网模块通信吗_php485对接NB-IoT模块实例【说明】  C++中的协变与逆变是什么?C++函数指针与返回类型详解【类型系统】  Win11怎么关闭VBS安全性_Windows11提升游戏性能关闭虚拟化安全  Python与Docker容器化部署实战_镜像构建与CI/CD流程  Python路径拼接规范_跨平台处理说明【指导】  Win11怎样安装搜狗输入法_Win11安装搜狗输入法教程【步骤】  c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】  Win10怎么限制单程序CPU占用上限_Win10任务管理器亲和性或第三方工具均衡负载【技巧】  php下载安装包太大怎么下载_分卷压缩下载方法【教程】  Win10如何卸载Skype_Win10卸载Skype步骤【步骤】  Win11怎么把图标拖到任务栏_Win11固定应用快捷方式指南【方法】  Win11如何设置自动关机 Win11定时关机命令使用教程【技巧】  Win11怎么设置快速访问_Windows11文件资源管理器主页  php8.4匿名类怎么用_php8.4匿名类创建与使用场景【介绍】  Win11 explorer.exe频繁崩溃_修复Win11资源管理器无限重启【步骤】 

 2025-12-30

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.