【C++进阶】面试官常考的关于多态一些常见问题!!!

发布时间:2026/6/19 18:35:59

【C++进阶】面试官常考的关于多态一些常见问题!!! 多态考察的一些常见问题参考链接点击跳转1.什么是多态答多态Polymorphism是面向对象编程的三大特性之一指同一操作作用于不同的对象可以有不同的解释产生不同的执行结果。简而言之即一个接口多种实现。其核心在于通过基类的指针或引用来调用派生类的虚函数在运行时决定具体执行哪个函数从而实现接口与实现的分离。详细定义、分类编译时多态与运行时多态及示例请参考链接内容。2什么是重载、重写覆盖、重定义隐藏答这是C中三个容易混淆的重要概念重载Overload发生在同一作用域内如一个类中函数名相同但参数列表类型、顺序、数量不同。编译器在编译期根据参数决定调用哪个函数属于静态多态。重写/覆盖Override发生在继承体系中派生类重新定义基类中的虚函数要求函数名、参数列表、返回类型协变返回类型除外都必须相同。通过虚函数表实现是运行时多态的关键。重定义/隐藏Hide发生在继承体系中如果派生类定义了与基类同名的非虚函数或者参数列表不同的同名函数则会隐藏基类中的所有同名函数。调用时取决于对象的静态类型。三者的区别图参考链接内容3多态的实现原理答C运行时多态的核心实现机制依赖于虚函数表Virtual Table vtable和虚函数表指针vptr。每个包含虚函数的类都有一个对应的虚函数表表中存放了该类所有虚函数的地址。该类的每个对象内部都隐含一个vptr指针指向这个表。当通过基类指针或引用调用虚函数时程序在运行时会通过对象的vptr找到正确的虚函数表进而从表中取出目标函数的地址进行调用。这个过程实现了动态绑定。4.inline函数可以是虚函数吗答可以不过编译器会忽略 inline 属性这个函数就不再是 inline 函数了。为什么可以声明为虚函数从语法层面C 允许将inline关键字与virtual关键字同时用于成员函数的声明。编译器不会因为这两个关键字同时出现而报错。为什么 inline 属性会被忽略虚函数virtual function的实现依赖于虚函数表vtable和虚函数表指针vptr。每个含有虚函数的类或其派生类的对象内部都有一个 vptr指向该类对应的虚函数表。当通过基类指针或引用调用虚函数时程序会在运行时通过 vptr 找到虚函数表再从表中取出正确的函数地址进行调用。这个过程称为动态绑定或晚期绑定。inline函数内联函数的处理发生在编译期。编译器尝试将函数调用处直接替换为函数体以消除函数调用的开销。这个替换过程要求编译器在编译时就必须知道具体要调用哪个函数。这里就产生了根本矛盾虚函数的调用在运行时才能确定具体调用哪个版本基类还是派生类。内联展开需要在编译时就确定函数体并进行替换。由于虚函数的“运行时决议”特性编译器无法在编译期确定应该内联哪个函数体是基类的还是某个派生类的。因此为了保证虚函数机制的正确运行编译器会忽略声明在虚函数上的inline关键字将其当作普通的虚函数来处理即将其地址放入虚函数表通过指针间接调用。5静态成员可以是虚函数吗答不能因为静态成员函数没有 this 指针使用类型::成员函数的调用方式无法访问虚函数表所以静态成员函数无法放进虚函数表。6.构造函数可以是虚函数吗答不能因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。调用构造函数之前要在虚函数表里找但这是还没有虚函数表7析构函数可以是虚函数吗什么场景下析构函数是虚函数答可以并且最好把基类的析构函数定义成虚函数。8对象访问普通函数快还是虚函数更快答首先如果是普通对象调用是一样快的。如果是指针或者是引用对去调用则调用的普通函数快因为构成多态运行时调用虚函数需要到虚函数表中去查找。9虚函数表是在什么阶段生成的存在哪的答虚函数表是在编译阶段就生成的一般情况下存在代码段常量区的。10.C菱形继承的问题虚继承的原理答C中的菱形继承Diamond Inheritance是指一个派生类通过两条或更多路径继承自同一个基类这会导致派生类对象中包含多份基类子对象从而引发数据冗余和二义性问题。虚继承Virtual Inheritance正是为解决菱形继承问题而引入的机制。通过使用virtual关键字修饰继承关系可以确保在继承体系中无论经过多少条路径最终派生类中只包含一份共享的基类子对象。其原理是编译器会为虚继承的类生成一个虚基表指针vbptr和对应的虚基表vbtable用于在运行时定位唯一的基类子对象。关键区别虚函数表vtable用于实现多态存储虚函数地址虚基表vbtable用于解决菱形继承中的数据冗余存储虚基类的偏移量。两者作用不同切勿混淆。11.什么是抽象类抽象类的作用答抽象类Abstract Class是指包含至少一个纯虚函数Pure Virtual Function的类纯虚函数通过在声明末尾添加 0来定义。抽象类不能被实例化即不能创建该类的对象。抽象类的主要作用包括定义接口规范抽象类为派生类定义了一组必须实现的接口纯虚函数强制派生类遵循特定的行为契约。实现接口继承它体现了“接口继承”关系即派生类继承的是基类的接口行为规范而不仅仅是实现。这有助于设计出灵活、可扩展的系统架构。实现多态通过基类抽象类指针或引用可以调用不同派生类对纯虚函数的具体实现这是运行时多态的核心应用场景之一。简而言之抽象类通过纯虚函数强制派生类完成特定功能的实现从而实现了接口与实现的分离是面向对象设计中实现多态和制定规范的重要工具。

相关新闻