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

参考资料:阿秀

一、面向对象三大特性

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

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

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

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

实现多态的两种方式:

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

二、虚函数

        在基类的函数前加上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://www.mzph.cn/diannao/43708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库课设---学生宿舍管理系统(sql server+C#)

1.引言 1.1 内容及要求 设计内容&#xff1a;设计学生宿舍管理系统。 设计要求&#xff1a; &#xff08;1&#xff09;数据库应用系统开发的需求分析&#xff0c;写出比较完善系统功能。 &#xff08;2&#xff09;数据库概念模型设计、逻辑模型设计以及物理模型设计。 …

yolov8 人体姿态识别

引言 在计算机视觉的各种应用中&#xff0c;人体姿态检测是一项极具挑战性的任务&#xff0c;它能够帮助我们理解人体各部位的空间位置。本文将详细介绍如何使用 YOLOv8 和 Python 实现一个人体姿态检测系统&#xff0c;涵盖模型加载、图像预处理、姿态预测到结果可视化的全流…

Echarts水球图(liquidFill)添加文字

效果 代码 {type: liquidFill,shape: shapes[0].value,radius: 90%,data: [{name: 独立百货,value: 0}],center: [50%, 50%],color: [{type: linear,x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: #446bf5},{offset: 1,color: #2ca3e2}],globalCoord: false}],backgro…

JSP实现简单的登录和注册

JSP实现登录和注册&#xff08;Map集合模拟数据库&#xff09; 1、login.jsp2、 loginSelect.jsp3、register.jsp4、 RegisterSelect.jsp5、 index.jsp 1、login.jsp login.jsp中username和password在LoginSelect.jsp验证是否一致使用session.setAttribute("login_msg&quo…

【RHCE】dns实验0707

题目&#xff1a; 做法: 1.创建两个虚拟机 张三&#xff1a;且有加密 李四&#xff1a; 设置zhangsan/lisi对应的html网页 主服务器测试&#xff1a; 证书验证 2.配置dns 主服务器&#xff1a; 区域文件&#xff08;zs/lisi&#xff09; 从服务器&#xff1a; 且dns为主服务…

OZON生活家居用品爆款新品

OZON生活家居用品爆款新品涵盖了多个方面&#xff0c;这些产品不仅满足了消费者对生活品质的追求&#xff0c;也反映了当前市场的热门趋势。以下是一些在OZON平台上备受关注的生活家居用品爆款新品&#xff1a; OZON生活家居用品爆款新品工具&#xff1a;D。DDqbt。COm/74rD T…

Midway Serverless 发布 2

可以看看优化后的开发情况&#xff0c;不仅和应用一样&#xff0c;速度还比较快&#xff0c;也不会生成临时目录&#xff0c;修改实时生效。 这是 v2.0 和 v1.0 的根本性变化&#xff0c;也是整体架构升级带来的巨大优势。 当然&#xff0c;这一块并不是功能的新增&#xff0c…

电脑清理c盘内存空间怎么清理免费 怎么清理c盘的垃圾文件又不删除有用文件

在计算机使用过程中&#xff0c;随着时间的推移&#xff0c;C盘空间可能会被各种临时文件、缓存和无用的注册表项占用。这不仅会导致C盘空间不足&#xff0c;还可能影响计算机的性能。那么怎么样清理C盘内存空间&#xff0c;怎么样清理C盘的垃圾避开系统文件呢&#xff1f; 一…

数据分析案例-2024 年全电动汽车数据集可视化分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Navicat BI 教程 | 图表设计和仪表板

商业智能&#xff08;Business Intelligence&#xff0c;BI&#xff09;是将数据转化为可操作的洞察力的实践&#xff0c;使组织能够简化生产力和实现更好的整体绩效。本博客最近介绍了新的 Navicat BI&#xff0c;这是一个帮助 BI 专业人员通过创建数据可视化&#xff08;如图…

侯捷C++面向对象高级编程(上)-11-虚函数与多态

1.虚函数 2.virtual 3.继承&#xff0b;复合关系下的构造和析构 4.委托&#xff0b;继承

C语言 | Leetcode C语言题解之第221题最大正方形

题目&#xff1a; 题解&#xff1a; int maximalSquare(char** matrix, int matrixSize, int* matrixColSize){int dp[301][301]{0};int wid0;if(matrixSize0&&matrixColSize[0]0){return 0;}for(int i0;i<matrixSize;i){for(int j0;j<matrixColSize[0];j){if(m…

Docker进入MongoDB

先是命令行开启docker镜像&#xff0c;然后进入docker镜像&#xff0c;这是两步 进入之后&#xff0c;开头会变成root&#xff0c;我的理解是进入了另一个linux系统了&#xff0c;直接执行相应的软件 这里直接use databse就是进入了&#xff0c;据说MongoDB是慢启动&#xff0c…

MMGPL: 多模态医学数据分析与图提示学习| 文献速递-基于深度学习的多模态数据分析与生存分析

Title 题目 MMGPL: Multimodal Medical Data Analysis with Graph Prompt Learning MMGPL: 多模态医学数据分析与图提示学习 01 文献速递介绍 神经学障碍&#xff0c;包括自闭症谱系障碍&#xff08;ASD&#xff09;&#xff08;Lord等&#xff0c;2018年&#xff09;和阿…

开发个人Go-ChatGPT–6 OpenUI

开发个人Go-ChatGPT–6 OpenUI Open-webui Open WebUI 是一种可扩展、功能丰富且用户友好的自托管 WebUI&#xff0c;旨在完全离线运行。它支持各种 LLM 运行器&#xff0c;包括 Ollama 和 OpenAI 兼容的 API。 功能 由于总所周知的原由&#xff0c;OpenAI 的接口需要密钥才…

Elasticsearch详细介绍

B站对应视频&#xff1a; Elasticsearch01-01.为什么学习elasticsearch_哔哩哔哩_bilibili 大多数日常项目&#xff0c;搜索肯定是访问频率最高的页面之一。目前搜索功能是基于数据库的模糊搜索来实现的&#xff0c;存在很多问题。 首先&#xff0c;查询效率较低。 由于数据…

数据结构 Java DS——链表部分经典题目 (1)

前言 笔者计划在暑假啃完JavaDS,Mysql的内容当然也会继续更 这次给读者们分享的是链表的几个比较典型的题目,关于如何手搓一个链表,笔者还在筹划中, 毕竟链表的种类也有那么多,但是在下面的题目中,只有单向链表 题目一 : 反转链表 206. 反转链表 - 力扣&#xff08;LeetCode…

什么是 VueQuill(前端的富文本编辑器)?

什么是 VueQuill&#xff1f; 1. 简介 VueQuill 是 Vue.js 的一个富文本编辑器插件&#xff0c;它基于 Quill 编辑器构建&#xff0c;提供了简洁且功能强大的富文本编辑功能。Quill 是一个现代化的富文本编辑器&#xff0c;提供丰富的文本编辑能力&#xff0c;支持多种格式和…

RockYou2024 发布史上最大密码凭证

参与 CTF 的每个人都至少使用过一次臭名昭著的rockyou.txt单词表&#xff0c;主要是为了执行密码破解活动。 该文件是一份包含1400 万个唯一密码的列表。 源自 2009 年的 RockYou 黑客攻击&#xff0c;创造了计算机安全历史。 多年来&#xff0c;“rockyou 系列”不断发展。…

爬虫怎么实现抓取的

1.4爬虫工程师常用的库通过图1-3我们了解到&#xff0c;爬虫程序的完整链条包括整理需求、分析目标、发出网络请求、文本解析、数据入库和数据出库。其中与代码紧密相关的有&#xff1a;发出网络请求、文本解析、数据入库和数据出库&#xff0c;接下来我们将学习不同阶段中爬虫…