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

参考资料:阿秀

一、面向对象三大特性

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

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

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

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

实现多态的两种方式:

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

二、虚函数

        在基类的函数前加上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,某些编译器会将其优化,合并为一个指针。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法小练之 位运算基础

前言 今天正式走入&#xff0c;位运算这个章节&#xff0c;关于这一部分我会先介绍几个重要的知识点&#xff0c;然后再根据几个力扣上的题来讲解。 了解6种位操作 总所周知&#xff0c;变量在计算机中都是二进制存储的&#xff0c;比如一个变量int a 1&#xff1b; 它的存…

Halcon 模糊圆边的找圆案例

Halcon 模糊圆边的找圆案例 基本思路 1.将图像转成灰度图像 2.再观察要找到的区域的灰度值变化&#xff0c;找到前景与背景的具体数值。 3.根据找到的前景与背景的具体数值&#xff0c;增强图像对比度。&#xff08;使图像变成黑白图片&#xff09; 4.使用灰度直图工具进行阈值…

gRPC 接口测试最佳实践

gRPC 是由谷歌开发的现代开源高性能 RPC 远程过程调用框架&#xff0c;由于采用了HTTP/2 作为底层传输协议&#xff0c;它特别适用于高性能应用场景。gRPC 在视频流传输等大规模数据传输场景以及密集的服务间通讯的微服务架构中表现出色。 数据交换使用轻量级的 Protobuf 序列…

18.按键消抖模块设计(使用状态机,独热码编码)

&#xff08;1&#xff09;设计意义&#xff1a;按键消抖主要针对的时机械弹性开关&#xff0c;当机械触点断开、闭合时&#xff0c;由于机械触点的弹性作用&#xff0c;一个按键开关在闭合时不会马上稳定地接通&#xff0c;在断开时也不会一下子就断开。因而在闭合以及断开的瞬…

Jmeter-接口测试-GET请求

简介 Jmeter 是 apache 公司基于 java 开发的一款开源压力测试工具&#xff0c;体积小&#xff0c;功能全&#xff0c;使用方便&#xff0c;是一个比较轻量级的测试工具&#xff0c;使用起来非常简 单。因为 jmeter 是 java 开发的&#xff0c;所以运行的时候必须先要安装 jdk…

数据结构——Trie

题目&#xff1a; 维护一个字符串集合&#xff0c;支持两种操作&#xff1a; I x 向集合中插入一个字符串 x&#x1d465;&#xff1b;Q x 询问一个字符串在集合中出现了多少次。 共有 N&#x1d441; 个操作&#xff0c;所有输入的字符串总长度不超过 10^5&#xff0c;字符串仅…

(HAL)stm32f407+freertos通过usb驱动移远4G模块-EC600U

概述 本篇文章主要介绍: 如何使用STM32CubeMX创建stm32F407+freertos+usb host的基础工程。USB-HOST-CDC驱动运行过程。如何根据4G模块的具体信息修改usb相关代码。MCU如何通过usb与4G模块通信,收发数据。调试过程中遇到的问题以及解决办法。 整个过程中在网上搜罗了很多参考…

Test-Time Adaptation via Conjugate Pseudo-labels--论文笔记

论文笔记 资料 1.代码地址 https://github.com/locuslab/tta_conjugate 2.论文地址 https://arxiv.org/abs/2207.09640 3.数据集地址 论文摘要的翻译 测试时间适应(TTA)指的是使神经网络适应分布变化&#xff0c;在测试时间仅访问来自新领域的未标记测试样本。以前的TT…

STM32(二):STM32工作原理

这里写目录标题 0、参考1、寄存器和存储器基本概念&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;主要区别&#xff08;3&#xff09;联系&#xff08;4&#xff09;实际应用中的案例&#xff08;5&#xff09;总结&#xff08;6&#xff09;一些名词解释 2、STM…

实时监测、智能预警:电缆光纤测温系统|原理、应用与前景

实时监测、智能预警&#xff1a;电缆光纤测温系统|原理、应用与前景 电缆光纤测温系统&#xff0c;作为现代电力系统中不可或缺的一部分&#xff0c;以其独特的优势在电缆安全监控领域发挥着日益重要的作用。该系统利用光纤传感技术&#xff0c;实时监测电缆的运行温度&#x…

Qt常用基础控件总结—带边框的部件(QFrame和QLabel)

带边框的部件 框架控件QFrame类 QFrame类介绍 QFrame 类是带有边框的部件的基类,带边框部件的特点是有一个明显的边框,QFrame类就是用来实现边框的不同效果的(把这种效果称为边框样式),所有继承自 QFrame 的子类都可以使用 QFrame 类实现的效果。 部件通常是矩形的(其他…

Kithara和OpenCV (一)

Kithara使用 OpenCV 目录 Kithara使用 OpenCV简介需求和支持的环境构建 OpenCV 库使用 CMake 进行配置以与 Kithara 一起工作 使用 OpenCV 库设置项目运行 OpenCV 代码图像采集和 OpenCV自动并行化限制和局限性1.系统建议2.实时限制3.不支持的功能和缺失的功能4.显示 OpenCV 对…

【Perforce】QAC-分析时如何不应用某些规则

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决扫描项目时如何不应用某些规则进行分析。 2、 问题场景 对于一些建议性的MISRA规则&#xff0c;不想用于项目扫描&#xff0c;如何处理&#xff1f; 3、软硬件环境 1、软件版本&#xff1a;HelixQAC23.04 2…

中国科学院院士丁汉:人形机器人——机器人与人工智能结合的爆发点

工业制造是国民经济的重要支柱&#xff0c;是实现发展升级的国之重器。早在 2002 年&#xff0c;党的十六大就曾提出&#xff0c;坚持以信息化带动工业化&#xff0c;以工业化促进信息化&#xff0c;走出一条科技含量高、经济效益好、资源消耗低、环境污染少、人力资源优势得到…

24年,计算机仍然是最热门的专业?!

大家好&#xff0c;我是程序员鱼皮。最近很多高考完的朋友开始进入了填志愿选专业的时期。出于好奇&#xff0c;我也在网上了解了一下今年的热门专业和就业情况&#xff0c;结果并没有出乎我的意料&#xff0c;对于很多省份&#xff0c;计算机科学与技术依然是最热门的专业&…

fastadmin 各种开发技巧,问题总合集,持续跟新中....

使用 搜索的使用 自定义按钮 需改后的代码 {field: operate, title: __(Operate), table: table,buttons: [{name: detail, text: 详情, title: 详情, icon: fa fa-list, classname: btn btn-xs btn-primary btn-dialog, url: version/detail},{name: edit, text: 编辑我, …

班级录取查询系统如何制作

在教育的长河中&#xff0c;我们每位老师都曾面临过这样一个问题&#xff1a;如何高效、准确地完成班级录取查询的任务&#xff1f;记得在以往&#xff0c;每当新学期伊始&#xff0c;我们不得不手忙脚乱地整理学生名单&#xff0c;然后逐一通知他们所在的班级。这个过程不仅耗…

【机器学习】特征选择:精炼数据,提升模型效能

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 特征选择&#xff1a;精炼数据&#xff0c;提升模型效能引言为何进行特征选择&a…

windows server安全设置,多次登录密码错误锁定

河北瑾航科技有限公司推荐&#xff0c;www.jinhangsmart.top 按快捷键【winr】&#xff0c;在【运行】框中输入“gpedit.msc”后回车。 进入【本地组策略编辑器】后&#xff0c;展开至&#xff1a;计算机配置—Windows设置—安全设置—帐户策略—帐户锁定策略。 双击右侧…

一次性语音芯片——智能家居的新兴技术

一次性语音芯片&#xff0c;作为现代智能家居技术&#xff0c;正以其魅力和性能&#xff0c;逐渐渗透到我们日常生活的每一个角落。这些小巧而强大的芯片&#xff0c;不仅为智能家居设备赋予了“说话”的能力&#xff0c;更在提升用户体验、增强设备交互性方面发挥了举足轻重的…