【面试八股总结】面向对象三大特性、虚函数、纯虚函数、虚继承

参考资料:阿秀

一、面向对象三大特性

封装:将数据和代码捆绑在一起,避免外界干扰和不确定性访问

继承:让某种类型对象获得另一个类型对象的属性和方法

多态:同一种事务表现出不同事务的能力,即:向不同对象发送同一消息,不同的对象在接收时会产生不同的行为

        重载实现编译时多态,虚函数实现运行时多态。

实现多态的两种方式:

  • 覆盖:子类重新定义父类的虚函数做法
  • 重载:允许存在多个同名函数,而这些函数的参数表不同(参数个数不同、或者参类型不同、或者两者都不同)

二、虚函数

        在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据所指对象的实际类型来调用相应的函数,如果对象类型是派生类,就调用派生类的函数,如果对象类型是基类,就调用基类的函数。

底层原理:

  • 虚表: 虚函数表的缩写,类中含有virtual关键字修饰的方法时,编译器会自动生成虚表
  • 虚表指针: 在含有虚函数的类实例化对象时,对象地址的前四个字节存储的指向虚表的指针

上图展示了虚表和虚表指针在基类对象和派生类对象中的模型,那么多态具体是如何实现的呢?

1. 对象初始化

  • 编译器会自动为每个含有虚函数的类生成一份虚表,该表时一个一维指针数组,虚表中保存了虚函数的入口地址。
  • 编译器会在每个对象的前四个字节中保存一个虚表指针vptr,指向对象所属类的虚表。在构造时,根据对象的类型初始化虚指针vptr,从而让虚指针指向正确的虚表。
  • 在派生类定义对象时,程序会自动调用构造函数,在构造函数中创建虚表并对虚表初始化。

2. 虚指针指向

  • 当派生类对基类的虚函数没有重写时,派生类的虚表指针指向的是基类的虚表;
  • 当派生类对基类的虚函数重写时,派生类的虚表指针指向的是自身的虚表;
  • 当派生类中有自己的虚函数时,在自己的虚表指针中将此虚函数地址添加在后面。

这样指向派生类的基类指针在运行时,可以根据派生类对虚函数重写情况动态进行调用,从而实现多态性。

构造函数和析构函数可以声明为虚函数吗?

        构造函数不能定义为虚函数,析构函数可以为虚函数,并且一般情况下基类析构函数都要定义为虚函数。

        构造函数:每个含有虚函数的类都有一个虚表指针,指向虚函数表。如果构造函数时虚函数,就需要通过虚表指针寻找虚函数表,从而找到对应的虚函数实现。但是类对象还没有初始化,就没有虚表指针,找不到虚函数,所以构造函数不能时虚函数。

        析构函数:只有在基类析构函数是虚函数时,调用delete操作符销毁指向派生类的基类指针时,才能准确调用派生类的析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。

三、纯虚函数

虚函数和纯虚函数的区别?

  • 虚函数是为了实现动态编译产⽣的,目的是通过基类类型的指针指向不同对象时,自动调用相应的、和基类同名的函数(使⽤同⼀种调用形式,既能调用派生类又能调用基类的同名函数)。虚函数需要在基类中加上 virtual修饰符修饰,因为virtual会被隐式继承,所以子类中相同函数都是虚函数。当⼀个成员函数被声明为虚函数之后,其派生类中同名函数自动成为虚函数,在派生类中重新定义此函数时要求函数名、返回值类型、参数个数和类型全部与基类函数相同。
  • 纯虚函数只是相当于⼀个接口名,但含有纯虚函数的类不能够实例化

纯虚函数首先是虚函数,其次没有函数体,取而代之使用“=0”代替。

它的函数指针会被存在虚函数表中,由于纯虚函数并没有具体的函数体,因此他在虚函数表中的值为0,其他有函数体的虚函数则是函数的具体地址。

一个类中如果存在纯虚函数,称为抽象类,抽象类不能用于实例化,一般用于定义一些公有方法。子类继承抽象类也必须实现其中的纯虚函数才能实例化对象。

四、虚拟继承

一个类可以从多个基类(父类)继承属性和行为。在C++等支持多重继承的语言中,一个派生类可以同时拥有多个基类。

多重继承可能引入一些问题,如萎形继承问题,比如当一个类同时继承了两个拥有相同基类的类,而最终的派生类又同时继承了这两个类时,可能导致二义性和代码设计上的复杂性。为了解决这些问题,C++ 提供了虚继承,通过在继承声明中使用 virtual 关键字,可以避免在派生类中生成多个基类的实例,从而解决了菱形继承带来的二义性。

举个🌰:

#include <iostream>using namespace std;class A{}class B : virtual public A{};class C : virtual public A{};class D : public B, public C{};int main(){cout << "sizeof(A):" << sizeof A <<endl; // 1,空对象,只有⼀个占位cout << "sizeof(B):" << sizeof B <<endl; // 4,⼀个bptr指针,省去占位,不需要对⻬cout << "sizeof(C):" << sizeof C <<endl; // 4,⼀个bptr指针,省去占位,不需要对⻬cout << "sizeof(D):" << sizeof D <<endl; // 8,两个bptr,省去占位,不需要对⻬}

上述代码所体现的关系是,B和C虚拟继承A,D公有继承B和C,这种方式是⼀种菱形继承或者钻石继承,可以用下图来表示:

        虚拟继承的情况下,无论基类被继承多少次,只会存在一个实体。

        虚拟继承基类的子类中,子类会增加某种形式的指针,或者指向虚基类子对象,或者指向一个相关表格;表格中存放的不是虚基类子对象的地址,就是其偏移量,此类指针被称为bptr。如果即存在vptr又存在bptr,某些编译器会将其优化,合并为一个指针。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3225255.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Git 详解(原理、使用)

git 快速上手请看这篇博客 Git 快速上手 1. 什么是 Git Git 是目前最主流的一个版本控制器&#xff0c;并且是分布式版本控制系统&#xff0c;可以控制电脑上所有格式的文档 版本控制器&#xff1a;记录每次修改以及版本迭代的管理系统 对于文本文件&#xff0c;可以记录每次…

Vue3项目如何使用npm link本地测试组件库

一、组件库操作 1、在组件库项目中先运行npm run lib&#xff0c;其效果如下 2、在组件库项目中在运行npm link&#xff0c;其效果如下 会创建一个全局的软连接指向本地的组件库 二、Vue3项目使用 1、在项目中运行 npm link 组件名称&#xff08;即&#xff1a;组件库packag…

【PB案例学习笔记】-30动态打开窗口

写在前面 这是PB案例学习笔记系列文章的第30篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

数电基础 - 数制,码制

目录 一. 简介 数制 码制 二. 进制 十进制&#xff08;Decimal&#xff09;&#xff1a; 二进制&#xff08;Binary&#xff09;&#xff1a; 八进制&#xff08;Octal&#xff09;&#xff1a; 十六进制&#xff08;Hexadecimal&#xff09;&#xff1a; 三. 进制的转…

Go语言---正则表达式

正则表达式是一种进行模式匹配和文本操纵的复杂而又强大的工具。虽然正则表达式比纯粹的文本匹配效率低&#xff0c;但是它却更灵活。按照它的语法规则&#xff0c;只需构造出的匹配模式就能够从原始文本中筛选出几乎任何你想要得到的字符组合。go语言的通过regexp标准包来实现…

外卖商城平台小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商家管理&#xff0c;骑手管理&#xff0c;商品类型管理&#xff0c;商品信息管理&#xff0c;订单信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品信息&#…

理解负载组电路-EAK负载电路解释

负载组具有安全、可靠、操作方便、使用寿命长等特点。了解控制、冷却和负载元件电路的布局和功能对于理解负载组的运行、为应用选择负载组和维护负载组非常重要。以下各节将描述这些电路。 EAK负荷组运行概述 负载组接收来自电源的电力&#xff0c;将其转换为热量&#xff0c;…

Spring Cloud Alibaba -- 分布式定时任务解决方案(轻量级、快速构建)(ShedLock 、@SchedulerLock )

文章目录 一、 ShedLock简介二、 SchedulerLock三、基于Mysql方式使用步骤1.建表2.引入依赖3.Mysql连接配置4.ScheduledLock配置5.启动类配置6.创建定时任务7.启动多个项目服务进行测试8.SchedulerLock注解说明 四、使用注意事项 一、 ShedLock简介 ShedLock 是一个用于 Java …

58、基于径向基神经网络的曲线拟合(matlab)

1、基于径向基神经网络的曲线拟合简介及原理 1&#xff09;原理简介 基于径向基神经网络&#xff08;Radial Basis Function Neural Network, RBFNN&#xff09;的曲线拟合是一种常用的非线性拟合方法&#xff0c;通过在输入空间中使用径向基函数对数据进行处理&#xff0c;实…

【机器学习】使用决策树分类器预测汽车安全性的研究与分析

文章目录 一、决策树算法简介决策树的结构分类和回归树 (CART)决策树算法术语决策树算法直觉 二、属性选择度量信息增益熵 基尼指数计算分割基尼指数的步骤 三、决策树算法中的过度拟合避免过度拟合的方法 四、导入库和数据可视化探索性数据分析重命名列名查看数据集的总结信息…

仪表板展示|DataEase看中国:2023年中国新能源汽车经济运行情况分析

背景介绍 随着政府机构、企业和个人对环保和可持续发展的高度关注&#xff0c;“新能源汽车”在全球范围内成为了一个热门话题。新能源汽车是指使用非传统燃料&#xff08;如电能、氢能等&#xff09;作为动力源的汽车。 在中国市场&#xff0c;新能源汽车产业蓬勃发展&#…

Python29 Tensorflow的基本知识和使用

1. TensorFlow TensorFlow 是一个开源的机器学习框架&#xff0c;由 Google Brain 团队开发。它用于数据流图的计算&#xff0c;尤其擅长深度学习任务。在 TensorFlow 中&#xff0c;数据流图&#xff08;Data Flow Graph&#xff09;是其核心概念之一&#xff0c;它定义了计算…

【QT】QComboBox允许输入查询,且不区分大小写

目录 0.简介 1.环境 2.详细代码 3.参考 0.简介 项目需求&#xff0c;原本有一个下拉框&#xff0c;但是条目太多&#xff0c;不好搜索&#xff0c;所以用户要求可以输入查找 修改前 &#xff1a; 修改后&#xff1a; 1.环境 windows11 vs-code qt5.12 2.详细代码 QComboB…

北斗防爆手持终端在化工厂的安全性能分析

北斗防爆手持终端在化工厂中的应用显著提升了安全性能&#xff0c;其卓越的防爆设计、高精度定位与监控功能、实时通信能力以及多功能集成特性&#xff0c;共同构筑了化工厂安全生产的坚实防线&#xff0c;确保了巡检人员与设备在复杂环境下的安全作业与高效管理。 北斗防爆手持…

触摸屏虚拟键盘组件 jQuery Virtual Keyboard使用 自定义键盘

如何在触摸设备上为输入域添加虚拟键盘&#xff1f; 一个插件可以解决这个问题&#xff0c;关键还支持高度自定义&#xff08;git地址&#xff09;&#xff1a; GitHub - Mottie/Keyboard: Virtual Keyboard using jQuery ~ 官网地址&#xff1a;Virtual Keyboard 使用步骤&…

免费下载工具 -- Free Download Manager(FDM) v6.24.0.5818

软件简介 Free Download Manager (FDM) 是一款免费的功能强大的下载管理软件&#xff0c;适用于多种操作系统&#xff0c;包括 Windows、macOS、Android 和 Linux。这款软件的特色在于它快速、安全且高效的下载能力。它可以下载各种热门网站的影片&#xff0c;支持 HTTP/HTTP…

人工智能算法工程师(中级)课程1-Opencv视觉处理之基本操作与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程1-Opencv视觉处理之基本操作与代码详解。OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它提供了各种视觉处理函数&am…

电脑虚拟摄像头怎么使用?电脑摄像头可以被虚拟摄像头替代吗?8款推荐!

在数字化日益普及的今天&#xff0c;视频通话和在线会议已成为我们生活和工作中不可或缺的一部分。然而&#xff0c;当我们的电脑没有配备摄像头&#xff0c;或摄像头出现故障时&#xff0c;我们可能会面临一些不便。这时&#xff0c;电脑虚拟摄像头便成为了一个实用的解决方案…

摸鱼大数据——Spark SQL——Spark on Hive部署

1、集成原理 HiveServer2的主要作用: 接收SQL语句&#xff0c;进行语法检查&#xff1b;解析SQL语句&#xff1b;优化&#xff1b;将SQL转变成MapReduce程序&#xff0c;提交到Yarn集群上运行​SparkSQL与Hive集成&#xff0c;实际上是替换掉HiveServer2。是SparkSQL中的HiveSe…

《AIGC:智能创作时代》:AI创作革命来临,你准备好了吗?

想象一下&#xff0c;你正在欣赏一幅精美的画作&#xff0c;惊叹于其细腻的笔触和独特的构图。然而&#xff0c;当你得知这幅作品是由人工智能创作时&#xff0c;你会作何感想&#xff1f;这不再是科幻小说中的场景&#xff0c;而是我们正在经历的现实。 在这个AI技术飞速发展的…