C++原型模式通过抽象基类声明clone()接口,具体类实现深拷贝逻辑,可选原型管理器按名注册与克隆,核心是对象自主克隆以解耦构造细节。
在 C++ 中实现原型模式,核心是让对象能“克隆自己”——通过定义一个统一的克隆接口,并由具体类自行实现深拷贝逻辑,从而避免紧耦合于构造细节,支持运行时动态创建类型未知的对象。
声明一个抽象基类(如 Prototype),提供纯虚函数 clone()。它不关心怎么复制,只约定“你能复制出一个新对象”。
注意:返回类型通常用智能指针(如 std::unique_ptr
示例:
class Prototype {
public:
virtual ~Prototype() = default;
virtual std::unique_ptr clone() const = 0;
};
每个可被克隆的具体类(如 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_; }
};
用一个简单注册表(如 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"); // 得到一份独立副本
原型模式不是万能的,C++ 实现中需特别留意:
clone() 会失效std::unique_ptr 或 std::shared_ptr 返回克隆结果,防止内存泄漏或误删clone() 声明为 const 成员函数,表示克隆不改变原对象状态原型模式在 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
致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。