c++如何实现模板方法模式 c++设计模式之Template Method【实例】


模板方法模式通过抽象基类定义算法骨架,将可变步骤延迟至派生类实现:基类以public final函数封装流程,protected virtual纯虚函数留扩展点,支持钩子机制与现代C++优化。

模板方法模式在C++中通过抽象基类定义算法骨架,将可变步骤延迟到派生类实现。核心是用virtual(常为protected)纯虚函数留出扩展点,用final防止关键步骤被重写,再以public非虚函数封装完整流程。

定义抽象模板类

声明一个含公共入口函数的基类,把不变逻辑写在该函数内,变化部分抽成受保护的虚函数:

  • 构造函数/析构函数设为protecteddefault,避免直接实例化
  • 模板主函数(如execute())为publicfinal,确保算法结构不被破坏
  • 子步骤(如step1()step2())为protectedvirtual,其中纯虚函数强制子类实现

派生类实现具体步骤

继承抽象类后,只重写需要定制的虚函数,不改变整体调用顺序:

  • 若某步有默认行为,基类中提供带实现的virtual函数;若必须重写,则用= 0声明纯虚
  • 可添加新成员变量或辅助函数,但不新增对外接口——所有交互仍走execute()
  • 示例:咖啡和茶的冲泡流程共用“烧水→冲泡→倒杯→加料”,仅“冲泡”和“加料”不同

支持钩子机制与默认行为

用带空实现的虚函数作为钩子(Hook),让子类选择性介入:

  • 例如isAddCondiments() { return true; },子类可重写返回false跳过加料
  • 钩子函数通常protectedvirtual、有默认实现,不影响主流程完整性
  • 避免在模板函数中直接调用private函数——那会封闭扩展能力

现代C++优化写法

C++11起可用override显式标注重写,C++17可结合if constexpr做编译期分支(适用于策略已知的场景):

  • 抽象类中用[[nodiscard]]标记execute(),提醒调用者注意返回值
  • 对无需多态的简单场景,也可用函数对象+模板参数替代继承(即“策略模式+模板”混合),但失去运行时切换能力
  • 慎用std::function代替虚函数——动态分配开销大,且破坏了模板方法的静态结构约束

不复杂但容易忽略:模板方法的价值不在代码量,而在把“什么不变”和“什么可变”清晰分离。只要基类里execute()没被绕过,算法一致性就始终可控。


# c++  # if  # 封装  # 多态  # 成员变量  # 子类  # 构造函数  # 析构函数  # 继承  # 虚函数  # 纯虚函数  # 接口  # public  # private  # protected  # function  # 对象  # default  # 算法  # 重写  # 派生类  # 抽象类  # 设为  # 而在  # 适用于  # 不被  # 但不  # 写在 


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


相关推荐: Win11如何设置自动关机 Win11定时关机命令使用教程【技巧】  windows 10专注助手怎么关闭_windows 10禁用通知提醒功能方法  Windows10如何更改桌面背景_Win10个性化幻灯片放映设置  如何使用Golang包导出规则_控制函数和变量可见性  Win10怎么卸载迅雷_Win10彻底卸载迅雷方法【步骤】  如何在Golang中实现WebSocket广播_使用Channel和协程分发消息  php485支持哪些操作系统_php485跨系统支持情况介绍【解答】  Linux如何安装Tomcat应用服务器_Linux环境部署与端口修改【教程】  如何处理“XML格式不正确”错误 常见XML well-formed问题解决方法  Win11怎样激活系统密钥_Win11系统密钥激活步骤【攻略】  Python模块的__name__属性如何由导入方式决定?  Win10闹钟铃声怎么自定义 Win10闹钟自定义铃声教程【方法】  Win11怎么关闭定位服务_保护Win11位置隐私设置指南【详解】  PowerShell怎么创建复杂的XML结构  php怎么下载安装后测试是否成功_简单脚本验证方法【操作】  Windows10系统怎么查看CPU核心数_Win10逻辑处理器数量查看  VSC怎样在Linux运行PHP_Ubuntu系统配置步骤【操作】  使用类变量定义字符串常量时如何实现类型安全的 Literal 注解  Win11怎么设置虚拟内存最佳大小_Windows11性能选项自定义分页文件  Win10怎么卸载爱奇艺_Win10彻底卸载爱奇艺方法【步骤】  Python大型项目拆分策略_模块化解析【教程】  VSC怎么在PHP中调试MySQL_数据库交互排查技巧【教程】  C#如何在一个XML文件中查找并替换文本内容  Linux怎么禁止Root用户远程登录_Linux系统SSH加固与安全设置【教程】  Win11此电脑不在桌面上_Windows 11桌面图标设置找回【步骤】  如何在 Go 应用中实现自动错误恢复与进程重启机制  Win11怎么开启剪贴板历史记录_Windows11 Win+V键使用技巧  MAC如何修改默认应用程序_MAC文件后缀关联设置与打开方式更改【教程】  php查询数据怎么导出csv_查询结果转csv文件保存【操作】  Win11资源管理器卡顿怎么办 Win11文件资源管理器重启技巧【优化】  Windows10系统怎么查看运行时间_Win10 CPU正常运行时间查询  Go 语言标准库为何不提供泛型 Contains 方法:设计哲学与类型系统约束  如何在Golang中优化文件读写性能_使用缓冲和并发处理  Django密码修改后会话失效的解决方案  Windows怎样关闭桌面弹窗广告_Windows关闭桌面弹窗设置【教程】  如何使用Golang log设置日志输出格式_Golang log日志格式示例  Windows10无法识别USB设备描述符请求失败_通用串行总线控制器修复  windows 10应用商店区域怎么改_windows 10微软商店切换地区方法  Win11怎样安装微信开发者工具_Win11安装开发者工具教程【步骤】  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  Windows10怎么用“讲述人”读屏辅助 Windows10轻松使用开启讲述人朗读屏幕文字帮助视障用户【教程】  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  PHP主流架构怎么集成Redis缓存_配置步骤【方法】  php8.4如何实现队列任务_php8.4redis队列简单实现方法【教程】  Windows10如何更改开机密码_Win10登录选项更改密码教程  Win11怎么激活Windows10_Win11激活Win10系统方法【步骤】  如何使用Golang管理跨项目依赖_Golang多模块项目依赖实践  php下载安装包怎么选_threadsafe与nts版本差异【解答】  如何使用正则表达式提取以编号开头、后接多个注解的逻辑分组块  Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递 

 2025-12-25

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

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

点击免费数据支持

提交您的需求,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.