
多态不是“用出来”的,是设计出来的
C++里没有“怎么用多态”这回事——你写不出多态,是因为类之间没建立起正确的继承+接口契约关系。动态多态依赖 vtable 和 virtual,静态多态靠模板推导;两者根本不在一个机制层上,混着讲容易误以为它们能互相替代。
virtual 函数必须在基类声明,且派生类重写要严格匹配签名
常见错误是派生类函数加了 const、改了返回类型、或参数用了值传递而非引用,结果编译不报错但调用不到——因为这不是重写,是重载或隐藏。
- 基类函数必须带
virtual,否则哪怕名字一样,ptr->func()也只认指针/引用的静态类型 - 派生类用
override关键字(C++11 起),编译器会检查是否真在重写;漏写override是很多运行时逻辑错位的源头 - 析构函数如果基类可能被多态删除,必须声明为
virtual ~Base() = default;,否则派生部分内存不释放
模板函数不是“静态多态”,std::variant 和 std::visit 才算现代静态分发
很多人把函数模板叫“静态多态”,其实它只是编译期重复实例化,和“同一接口不同行为”无关。真正用于替代虚函数、又避免运行时开销的,是 std::variant + std::visit 组合。
mallcloud商城基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba并采用前后端分离vue的企业级微服务敏捷开发系统架构。并引入组件化的思想实现高内聚低耦合,项目代码简洁注释丰富上手容易,适合学习和企业中使用。真正实现了基于RBAC、jwt和oauth2的无状态统一权限认证的解决方案,面向互联网设计同时适合B端和C端用户,支持CI/CD多环境部署,并提
-
std::variant<a b c></a>存一个确定类型的值,类型信息在编译期固定,无虚表、无指针间接跳转 -
std::visit([](auto&& x) { /* ... */ }, v)的 lambda 必须是泛型(auto&&),否则无法覆盖所有variant成员类型 - 不能对
std::variant做继承式扩展;新增类型就得改variant定义和所有visit分支,灵活性不如虚函数
别为了“多态”而多态:虚函数有真实成本,模板有膨胀风险
虚函数调用至少一次指针解引用(vtable 查表),在 tight loop 里可能被 CPU 分支预测器反复打脸;模板过度使用会让目标文件体积暴涨,链接慢,调试符号爆炸。
立即学习“C++免费学习笔记(深入)”;
- 高频调用路径(如图形渲染每帧千次以上)优先考虑
std::variant或策略类模板参数 - 接口稳定、子类经常增删的场景(比如插件系统),虚函数仍是更可维护的选择
-
final关键字加在类或虚函数上,能帮编译器内联——但只有确认不再继承时才加,否则后续扩展得改头换尾
虚函数表布局、RTTI 开关、模板隐式实例化点……这些细节不显式暴露,但实际影响二进制大小和运行时行为。想绕过它们,得先清楚自己在绕什么。








