news 2026/9/24 17:44:48

CRTP 编译期多态与静态接口:没有虚函数也能多态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CRTP 编译期多态与静态接口:没有虚函数也能多态

继承 + 虚函数不是 C++ 里实现「一套接口、多种实现」的唯一路子。如果你想要的是编译期就定下来的多态——没有运行期查虚表(virtual table,vtable)、调用能被内联(inline)、对象还更小——CRTP 就是这个需求的标准答案。这篇用真跑出来的sizeof和计数器实例,把 CRTP 到底是什么、为什么快、代价是什么讲清楚。

1. 引子:虚函数到底「贵」在哪

写惯了面向对象的人,要统一操作一批类型第一反应是抽个基类、把行为声明成virtual

structShape{virtualvoiddraw()=0;virtual~Shape()=default;};structCircle:Shape{voiddraw()override{/* ... */}};

这没问题,但隐藏三笔账:每个对象多一个 vptr(虚表指针)、每次调用draw()都要「取 vptr → 查表 → 跳转到函数」的间接跳转(indirect branch,会打分支预测)、整个类层级多了虚表数据。对性能敏感、或对象极多的场景,这三笔账可能不划算。CRTP 的卖点就是——把这些账全免了,代价是把「多态」从运行期挪到编译期。

官方文档:Curiously recurring template pattern — cppreference

2. CRTP 长什么样:派生类把自己喂给基类

CRTP 的骨架就一句话:基类是个模板,派生类继承「以自己为模板参数的基类」

// crtp_basic.cpp — 编译: g++ -std=c++17 -Wall -O2 crtp_basic.cpp -o cb#include<cstdio>template<classDerived>structShape{voiddraw()const{static_cast<constDerived*>(this)->draw_impl();}};structCircle:Shape<Circle>{voiddraw_impl()const{std::puts("Circle::draw");}};structSquare:Shape<Square>{voiddraw_impl()const{std::puts("Square::draw");}};intmain(){Circle c;c.draw();Square s;s.draw();
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 17:43:16

西安想做GEO优化的企业看过来!靠谱的GEO优化公司推荐

如果你还在天天琢磨如何给你的企业官网做SEO&#xff08;搜索引擎优化&#xff09;&#xff1f;那么你已经奥特了&#xff08;落后了&#xff09;。现在很多用户问问题不只通过传统搜索引擎&#xff08;譬如&#xff1a;360搜索、百度、搜狗搜索、神马搜索等&#xff09;去找答…

作者头像 李华
网站建设 2026/9/24 17:42:29

Qt — 输入类控件

目录 1. Line Edit 2. Text Edit 3. Combo Box 4. Spin Box 5. Date Edit & Time Edit 6. Dial 7. Slider 1. Line Edit QLineEdit ⽤来表示单行输入框. 可以输⼊⼀段⽂本, 但是不能换⾏. 核心属性 属性说明text输⼊框中的⽂本inputMask输⼊内容格式约束maxLength…

作者头像 李华
网站建设 2026/9/24 17:41:20

ROS2 实战 | 手写 TF2 海龟实时坐标广播器(含完整避坑指南)

ROS2 实战 | 手写 TF2 海龟实时坐标广播器(含完整避坑指南) 摘要:本文从零实现一个 ROS2 Python 节点,实时订阅 turtlesim 海龟位姿并广播 TF 坐标变换。重点修正了官方教程中常见的 Odometry/Pose 混用、__name__ 入口错误、--symlink-install 开发技巧等高频踩坑点,附完…

作者头像 李华