C++怎么用多态 C++静态多态与动态多态【详解】

1次阅读

C++怎么用多态 C++静态多态与动态多态【详解】

多态不是“用出来”的,是设计出来的

c++里没有“怎么用多态”这回事——你写不出多态,是因为类之间没建立起正确的继承+接口契约关系。动态多态依赖 vtablevirtual,静态多态靠模板推导;两者根本不在一个机制层上,混着讲容易误以为它们能互相替代。

virtual 函数必须在基类声明,且派生类重写要严格匹配签名

常见错误是派生类函数加了 const、改了返回类型、或参数用了值传递而非引用,结果编译不报错但调用不到——因为这不是重写,是重载或隐藏。

  • 基类函数必须带 virtual,否则哪怕名字一样,ptr->func() 也只认指针/引用的静态类型
  • 派生类用 override 关键字(C++11 起),编译器会检查是否真在重写;漏写 override 是很多运行时逻辑错位的源头
  • 析构函数如果基类可能被多态删除,必须声明为 virtual ~Base() = default;,否则派生部分内存不释放

模板函数不是“静态多态”,std::variantstd::visit 才算现代静态分发

很多人把函数模板叫“静态多态”,其实它只是编译期重复实例化,和“同一接口不同行为”无关。真正用于替代虚函数、又避免运行时开销的,是 std::variant + std::visit 组合。

  • 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 开关、模板隐式实例化点……这些细节不显式暴露,但实际影响二进制大小和运行时行为。想绕过它们,得先清楚自己在绕什么。

text=ZqhQzanResources