会,c++中通过基类引用调用虚函数可触发动态多态:需满足virtual声明、派生类重写、引用绑定完整派生对象三条件;直接用对象调用属静态绑定,构造/析构中调用虚函数也不触发多态。

会,只要满足三个基本条件:基类中该函数声明为 virtual、派生类重写了该函数、且调用是通过基类引用(而非对象本身)进行的。
通过基类引用调用虚函数确实触发多态
这是 C++ 动态多态的标准用法之一。引用的静态类型是基类,但实际绑定的对象是派生类实例,运行时会查虚函数表(vtable),调用派生类的重写版本。
- 必须用引用(
Base& r = derived;),不能是值传递(Base r = derived;会切片,丢失派生部分) - 引用必须绑定到派生类对象(或其 const/lvalue 引用),不能是临时对象被绑定到非常量左值引用
- 基类函数必须带
virtual,否则编译期就决定调用哪个函数(早绑定)
为什么直接用对象调用不触发多态
像 derived_obj.func() 这种写法,编译器在编译时就知道 derived_obj 是 Derived 类型,直接生成对 Derived::func 的调用指令,不经过 vptr/vtable 查找——这属于静态绑定,和多态无关。
- 多态只发生在“接口统一、实现分离”的场景:即调用方只知基类接口,不知具体派生类型
- 引用/指针提供了这种“类型擦除”能力;对象本身没有
- 即使函数是虚函数,直接调用也不走动态分发路径
构造函数和析构函数里调用虚函数不触发多态
这是最容易踩的坑。在基类构造函数执行期间,派生类部分尚未构造完成,此时即使通过 this 调用虚函数,也只会调用当前正在构造的类(比如基类)的版本,不会跳转到派生类重写版。
- 析构同理:派生类析构完成后才调基类析构,此时派生类部分已销毁
- 这种行为是标准规定的,不是 bug,而是为了保证对象状态安全
- 如果需要类似多态的行为,应显式设计为模板方法或回调机制
真正关键的不是“用了引用”,而是“引用是否指向完整构造的派生类对象”以及“虚函数表是否已就位”。这两点一旦出错,多态就静默失效,且很难调试。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











