当前位置: 首页 > news >正文

【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函数(内联函数)的处理发生在编译期。编译器尝试将函数调用处直接替换为函数体,以消除函数调用的开销。这个替换过程要求编译器在编译时就必须知道具体要调用哪个函数。

这里就产生了根本矛盾:

  1. 虚函数的调用在运行时才能确定具体调用哪个版本(基类还是派生类)。
  2. 内联展开需要在编译时就确定函数体并进行替换。

由于虚函数的“运行时决议”特性,编译器无法在编译期确定应该内联哪个函数体(是基类的还是某个派生类的)。因此,为了保证虚函数机制的正确运行,编译器会忽略声明在虚函数上的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来定义。抽象类不能被实例化,即不能创建该类的对象。

抽象类的主要作用包括:

  1. 定义接口规范:抽象类为派生类定义了一组必须实现的接口(纯虚函数),强制派生类遵循特定的行为契约。
  2. 实现接口继承:它体现了“接口继承”关系,即派生类继承的是基类的接口(行为规范),而不仅仅是实现。这有助于设计出灵活、可扩展的系统架构。
  3. 实现多态:通过基类(抽象类)指针或引用,可以调用不同派生类对纯虚函数的具体实现,这是运行时多态的核心应用场景之一。

简而言之,抽象类通过纯虚函数强制派生类完成特定功能的实现,从而实现了接口与实现的分离,是面向对象设计中实现多态和制定规范的重要工具。

http://www.jsqmd.com/news/909346/

相关文章:

  • 从自动化到自主化:构建会思考的安全代理架构与实战指南
  • 基于CircuitPython与3D打印的游戏计时器:从硬件选型到代码实现
  • 数字创作者工作流:技术、AI与自动化如何协同提升内容产出效率
  • Qwen3-VL-4B-Instruct在STEM领域的应用:数学推理与科学问题解决指南
  • 微算法科技(NASDAQ :MLGO)推出量子零知识证明共识机制,筑牢区块链安全防线
  • Anime4KCPP:让动漫图像重获新生的高性能超分辨率引擎 [特殊字符]
  • 2026年上海美业培训深度横评:化妆美甲美发零基础到高薪就业全链路指南 - 年度推荐企业名录
  • 你的知识存在哪里?PandaWiki + cpolar把本地知识库体验拉满
  • COM3D2.MaidFiddler:终极游戏实时编辑器,5分钟快速定制你的女仆角色!
  • 如何解决GoB插件在Blender 4.3中的导入问题:5个终极技巧
  • 新手也能看懂的CTF题复盘:从流量包里挖出Webshell和Frpc代理的完整攻击链
  • 原神帧率解锁终极指南:3步安全突破60FPS限制,释放硬件全部性能
  • FancyZones技术架构深度解析:从窗口管理到生产力革命
  • RAG从入门到精通:检索增强生成的完整技术栈
  • FGA自动化神器:重新定义FGO安卓玩家的战斗体验
  • BERT uncased L-12 H-256 A-4模型架构详解:12层256隐藏层的设计奥秘
  • 让聊天记录成为数字资产:WeChatMsg打造你的专属记忆银行
  • 2026 东莞翡翠回收精选商户:专业团队鉴定,本地交易安全稳妥 - 薛定谔的梨花猫
  • 如何永久保存你的微信聊天记录:开源解决方案完全指南
  • 安全审计实战指南:Python 日志实现与 GDPR 合规深度解析
  • BERT uncased L-12 H-256 A-4在不同NLP任务上的表现评估:轻量级模型的终极指南
  • 5分钟学会SillyTavern:打造属于你的AI角色对话神器
  • Dart Simple Live:多平台直播聚合应用架构设计与实现方案
  • 2026年精密测头十大品牌/厂家推荐榜:常规/多截面/多几何测头、圆柱度/锥度/垂直度测头等非标定制公司深度解析 - 企业推荐官【官方】
  • Keil C251中ECODE段与混合编程实践
  • imFile:一款全能下载管理器如何彻底解决你的下载难题
  • 如何免费解锁WeMod Pro功能:终极Wand增强工具配置指南
  • 智慧树自动刷课插件:告别手动操作,开启高效学习新时代
  • 量子退火解决集合分割问题的QUBO建模与实践
  • 别再只盯着串联机械臂了!5自由度并联机械臂的搬运应用实战,精度与刚性实测