C++中虚函数的作用是什么?为何示例输出存在差异?
你已经通过代码直观看到了有无virtual关键字的输出差异,核心原因在于函数绑定的时机不同——静态绑定 vs 动态绑定,这也是虚函数的核心价值所在。
先聚焦核心差异点
你的两个程序唯一的区别就是基类Name中的myName()是否加了virtual关键字,而输出差异完全集中在这行代码的行为上:
Name *nm; LName ln; nm = &ln; nm->myName(); // 这行的调用逻辑是关键
1. 不使用virtual时:静态绑定(编译期确定调用逻辑)
当基类的函数没有virtual修饰时,C++会采用静态绑定——编译器在编译阶段就根据指针的声明类型(这里nm是Name*类型)来锁定要调用的函数,完全不管指针实际指向的对象是什么类型。
所以哪怕nm实际指向的是LName对象,编译器依然会绑定Name::myName(),这就是你看到输出My First Name is Varun的原因。
2. 使用virtual时:动态绑定(运行期确定调用逻辑)
当基类的函数被virtual修饰后,这个函数就成为了虚函数,C++会启用动态绑定:程序运行时,会根据指针实际指向的对象类型(这里是LName对象)来调用对应的派生类重写函数。
所以此时nm->myName()会调用LName::myName(),输出My Last Name is Srivastava。
虚函数的核心作用
虚函数是C++实现多态性的核心机制:它允许你通过基类的指针或引用,统一处理不同的派生类对象,不需要针对每个派生类写单独的分支逻辑。比如你如果后续新增MiddleName这类继承自Name的类,只要它们重写了myName(),用基类指针调用时都会自动匹配对应类的版本,极大提升代码的扩展性和可维护性。
额外提个小细节:一旦基类声明了虚函数,派生类中重写该函数时可以不用重复写virtual(不过建议写上,可读性会更好),它依然会被视为虚函数。
内容的提问来源于stack exchange,提问作者Varun Srivastava

