每日一面——虚拟继承、抽象类和四种类型转化

news2025/10/20 3:35:49

写前声明:参考链接 C++面经、面试宝典 等

✊✊✊每日一面——虚拟继承、抽象类和四种类型转化

    • 一、什么是虚拟继承?
    • 二、如何理解抽象类?
    • 三、抽象基类为什么不能创建对象?
    • 四、成员函数里memset(this,0,sizeof(*this))会发生什么
    • 五、强制类型转换有哪几种,分别有哪些特点?原理是什么?

一、什么是虚拟继承?

  • C++支持多继承,除了public、private、protected三中继承方式外,还提供虚拟继承 virtual ,如果类B和类C同时公有继承类A,而类D有多重继承类B、C,这这种方式被叫做菱形继承
  • 虚拟继承的情况下,无论基类被继承多少次,只会存在一个实体
  • 虚拟继承基类的子类中,子类会增加某种形式的指针,或者指向虚基类对象,或者指向一个相关的表格;表格中存放的不是虚基类子对象的地址,就是其偏移量,此类这种被称为虚基类指针 bptr,而表格则是虚基类表,如果既存在虚函数指针,又存在虚基类指针,某些编译器会将其优化为一个指针
  • 在虚拟继承下,无论一个公有的基类子对象在派生类层次中出现了多少次,只会有一个共享的基类子对象被继承,共享的基类子对象就是虚基类,在此机制下,基类子对象的多份复制产生的二义性问题就被消除了

二、如何理解抽象类?

  • 抽象类的定义如下

    • 纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加 “=0”,就叫做抽象类
      抽象类有如下几个特点:
  • 抽象类有如下几个特点:

    • 1)抽象类只能用作其他类的基类,不能建立抽象类对象。
    • 2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。
    • 3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性

三、抽象基类为什么不能创建对象?

抽象类是一种特殊的类,它是为了抽象和设计目的来建立的,处于继承层次结构的较上层

  1. 抽象类的定义: 带有纯虚函数的类

  2. 抽象类的作用: 将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。所以派生类实际上刻画了一组子类的操作接口的通用语义,将其传给子类,子类可以具体实现这些语义,也可以将其传给自己的子类

  3. 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。 如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体的类。抽象类是不能定义对象的。一个纯虚函数不需要(但是可以)被定义

  4. 纯虚函数定义: 纯虚函数是一种特殊的虚函数,它的一般格式为:class <类名>  {  virtual <类型><函数名>(<参数表>)=0;  …  };

    • 在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。 纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务。除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。
  5. 纯虚函数引入原因:

    • 为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
    • 在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔 雀等子类,但动物本身生成对象明显不合常理。为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;)。若要使派生类为非抽象类,则编译器要求在派生类中,必须对纯虚函数予以重载以实现多态性。同时含有纯虚函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。例如,绘画程序中,shape作为一个基类可以派生出圆形、矩形、正方形、梯形等, 如果我要求面积总和的话,那么会可以使用一个 shape * 的数组,只要依次调用派生类的area()函数了。如果不用接口就没法定义成数组,因为既可以是circle ,也可以是square ,而且以后还可能加上rectangle,等等.

四、成员函数里memset(this,0,sizeof(*this))会发生什么

  • 类函数有虚函数表:这么做会破坏虚函数表,后续对虚函数的调用都将出现异常
  • 类中含有C++类型的对象:如,类中定义了一个list的对象,由于在构造函数体的代码执行之前就对list对象完成了初始化,假设list在它的构造函数里分配了内存,那么我们这么一做就破坏了list对象的内存。

五、强制类型转换有哪几种,分别有哪些特点?原理是什么?

Static_cast: 用于数据类型的强制转换,强制将一种数据类型转换为另一种数据类型,主要突出一个 联系!!!

- 主要用法:
	- 用于类层次结构中基类和派生类之间指针或者引用的转换,进行上行切换(把派生类的指针或者引用转换成基类)是安全的,若是下行转换,由于没有动态类型检查,不安全
	- 用于基本数据类型的转换,如 int -> char
	- 把空指针转换成目标类型的空指针
	- 把任意类型的表达式转换成void类型
- 

Const_cast: 用于强制去除类似于const这种不能被修改的常数特性

- 用法:
	- 用来修改类型的const或者volatile属性,除了const或volatile修饰之外,type_id和expression的类型是一样的。
	- 常量指针被转化为非常量指针,并且仍然指向原来的对象
	- 常量引用被转换为非常量引用,并且仍指向原来的对象,常量对象被转换成非常量对象。

注意:const_cast不适用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,即去除常量性的对象必须为指针或者引用。

Reinterpret_cast: 用于改变指针或引用的类型,将指针或者引用转换成一个足够长的整形,将整形转换为指针或引用

- 用法:
	- 传入一个类型必须是一个指针,引用,算术类型,函数指针,成员函数,成员指针
	- 它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针

Dynamic_cast: 其他三种都是在编译时完成的,它是在运行时处理的,运行时要进行类型检查。

- 用法:
	- 不能用于内置的基本数据类型的强制转换。
	- 如果转换成功会返回一个指向类的指针或者引用,转换失败会返回NULL。
	- 进行转换的时候基类中一定要有虚函数,否则编译不通过(因为类中存在虚函数就说明它有想让基类指针或引用指向派生类对象的情况,此时转换才有意义)。
	- 在类的转换时,在类层次间进行上行转换时,与static_cast的转换效果是一样的,在下行转换时,它具有类型检查功能,比static_cast更安全。

注意:向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。如果转换目标是指针类型转换失败,则结果返回0,如果是引用类型则抛出std::bad_cast异常

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

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

相关文章

three.js 鼠标左右拖动改变玩家视角

这里主要用到了 一个方法 obj.getWorldDirection(); obj.getWorldDirection()表示的获取obj对象自身z轴正方向在世界坐标空间中的方向。 按下 W键前进运动&#xff1b; <template><div><el-container><el-main><div class"box-card-left…

Qt(C++) | QPropertyAnimation动画(移动、缩放、透明)篇

动画类继承关系图 # QPropertyAnimation QPropertyAnimation是一个可以在Qt应用程序中使用的动画框架。它可以用于创建各种动画效果,包括但不限于以下几种: 1. 移动动画:可以将一个对象从一个位置平滑地移动到另一个位置。比如,你可以创建一个按钮,当用户点击它时,按钮…

Python语法基础

Python 运行方式 交互解释器&#xff1a;进入交互解释器 Pycharm 里面有个 Terminal 终端&#xff0c;点击即可进入Python的交互环境 语句快缩进 同行多个语句 输出语句:print 输入语句: 变量定义: 变量赋值: 运算符: 基本数字类型: 数字表示方法: 定义字符串: 定义列表:

【Vue3】深入理解Vue3路由器的工作原理to的两种写法

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

整块代码自动生成、智能括号匹配……CodeGeeX编程提效,功能再升级!

CodeGeeX插件功能持续打磨&#xff0c;希望成为开发者更高效的智能编程工具&#xff0c;提高开发速度和代码质量。今天介绍VSCode中最新的v2.4.0版本插件新功能&#xff0c;让你在编写代码时更加得心应手。 一、新增block代码块生成的设置 CodeGeeX插件中&#xff0c;以往针对…

读西游记第一回:西游记世界格局

天地之数&#xff1a; 元&#xff1a;十二万九千六百岁&#xff08;129600年&#xff09; 1元12会&#xff1a;子、丑、寅、卯、巳、午、未、申、酉、戌、亥。每会18000年。与12地支对应。 亥会期&#xff1a;前5400年混沌期&#xff0c;后5400年&#xff0c;盘古开天辟地&am…

【阿里云系列】-ACK的Java应用POD无法访问云数据库Redis

问题介绍 如下图所示&#xff0c;是ACK集群的POD访问阿里云的云数据库Redis&#xff0c;如何实现访问呢 配置步骤 要实现ACK集群内的所有POD都可以访问云数据库Redis&#xff0c;则需要在Redsi的白名单里增加源IP或网段&#xff0c;如下图所示 注意&#xff1a; 以上添加…

小型校园网配置笔记

1&#xff0c;搭建网络拓扑图 LSW1:三层交换机命令&#xff1a; <Huawei>sys [Huawei]undo info-center enable Info: Information center is disabled. [Huawei]vlan batch 10 20 30 40 100 101 [Huawei]int vlan 10 [Huawei-Vlanif10]ip add 192.168.10.254 24 …

PyTorch之完整的神经网络模型训练

简单的示例&#xff1a; 在PyTorch中&#xff0c;可以使用nn.Module类来定义神经网络模型。以下是一个示例的神经网络模型定义的代码&#xff1a; import torch import torch.nn as nnclass MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()# 定义神经…

sqllab第九关通关笔记

知识点&#xff1a; 时间盲注&#xff1a;利用休眠时间进行判断是否注入成功利用bp时注意把timeout时间修改一下 首先判断注入类型 构造id1/0 返回正常信息&#xff0c;应该是字符型注入 构造id1 返回正常信息&#xff0c;欸&#xff0c;这就怪了 构造id1 正常显示内容&am…

Lombok简介、使用、工作原理、优缺点

学习目标&#xff1a; 目标 Lombok简介、使用、工作原理、优缺点 学习内容&#xff1a; 内容 定义 Lombok 是一个 Java 库&#xff0c;它提供了很多有用的注解来简化 Java 代码的编写。 作用&#xff1a; 使用 Lombok 可以用一些简洁的注解来自动生成大量常见的 Java 代码&a…

EI会议----2024年控制技术、自动化与绿色城市规划国际学术会议(TAUGCP 2024)

EI会议----2024年控制技术、自动化与绿色城市规划国际学术会议(TAUGCP 2024) 2024 International Conference on Control Technology, Automation and Green Urban Planning(TAUGCP 2024) 大会主题&#xff1a;&#xff08;主题包括但不限于这些,更多详细主题请咨询苏老师&am…

缓存的使用

文章目录 1.为什么要有缓存&#xff1f;2.缓存使用场景3.缓存分类4.缓存使用模式5.淘汰策略6.缓存的崩溃与修复7.缓存最佳实践参考文献 1.为什么要有缓存&#xff1f; 数据访问具有局部性&#xff0c;符合二八定律&#xff1a;80% 的数据访问集中在 20% 的数据上&#xff0c;这…

Nuxt3: useFetch使用过程常见一种报错

一、问题描述 先看一段代码&#xff1a; <script setup> const fetchData async () > {const { data, error } await useFetch(https://api.publicapis.org/entries);const { data: data2, error: error2 } await useFetch(https://api.publicapis.org/entries);…

展会邀约 | 加速科技将携重磅产品亮相SEMICON China 2024

SEMICON China 2024将于3月20日-3月22日在上海新国际博览中心隆重举行。展会期间&#xff0c;加速科技将携重磅产品高性能数模混合信号测试机ST2500EX、LCD Driver测试机Flex10K-L、高密度数模混合信号测试系统ST2500E、高性能数模混合信号测试系统ST2500A亮相此次行业盛会&…

[Java、Android面试]_02_HashMap的原理

本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料&#xff0c;感兴趣的朋友可收藏关注。由于时间有限&#xff0c;只能每天整理一点&#xff0c;分享一点儿&#xff01; 现分享如下&#xf…

vue3/vue2若依框架对比,点击新增编辑跳转到新页面(新增编辑共用代码)

vue2若依框架&#xff1a; router里面定义好&#xff0c;编辑里面添加一个id {path: /filmManagement,component: Layout,hidden: true,redirect: noredirect,children: [{path: editFilmDetail,component: () > import(/views/filmManagement/editFilmDetail),name: editFi…

【Mac】鼠标控制\移动\调整窗口大小BBT|边缘触发调整音量\切换桌面

一直在 win 习惯了通过鼠标的侧键来控制窗口的位置、大小&#xff0c;现在找到心的解决方案了&#xff0c;通过 BBT 设置侧键按下\抬起几颗。 以下解决方案的截图&#xff0c;其中还包括了其他操作优化方案&#xff1b; 滚轮配合 cmd 键调节页面大小&#xff1b;配合 option 键…

探索C++中的动态数组:实现自己的Vector容器

&#x1f389;个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生 &#x1f648;个人主页&#x1f389;&#xff1a;GOTXX &#x1f43c;个人WeChat&#xff1a;ILXOXVJE &#x1f43c;本文由GOTXX原创&#xff0c;首发CSDN&…

算法思想总结:双指针算法

一、移动零 . - 力扣&#xff08;LeetCode&#xff09; 移动零 该题重要信息&#xff1a;1、保持非0元素的相对位置。2、原地对数组进行操作 思路&#xff1a;双指针算法 class Solution { public:void moveZeroes(vector<int>& nums){int nnums.size();for(int cur…