C++面试之继承和多态

news2024/10/9 14:04:18

(倒反天罡) 概念选择题答案(0411-0422)

1 C        2 A        3 B        4 B        5 D        6 D        7 D        8 C        9 D        10 D        11 C

12 E        13 C

继承有什么作用?

继承可以重写或重定义父类中的一些方法,这在一定程度上破坏了父类的 "封装性",注意这里所谓的破坏指的只是创建子类对象后,父类的一些封装好的方法将发生变化。

继承和组合有什么区别?

继承和组合的区别见下表

继承组合
父类实现的方法对于子类来说是可见的父类实现的方法对于子类来说是不可见的
子类中对父类方法的复用属于静态复用(白箱复用)子类中对父类方法的复用属于动态复用(黑箱复用)

由于在继承中,子类高度依赖父类,所以在设计类与类之间的关系时,更多使用的是组合

好了,看了上面的内容,做一下下面这道题吧

(C++ 1)面向对象设计中的继承和组合,下面说法错误的是?()

A :继承允许我们覆盖重写父类的实现细节,父类的实现对于子类是可见的,是一种静态复
用,也称为白盒复用
B :组合的对象不需要关心各自的实现细节,之间的关系是在运行时候才确定的,是一种动
态复用,也称为黑盒复用
C :优先使用继承,而不是组合,是面向对象设计的第二原则
D :继承可以使子类能自动继承父类的接口,但在设计模式中认为这是一种破坏了父类的封
装性的表现
抽象类的存在就是为了在抽象类中划分出更多具体的子类
一个类是抽象类  等价于  这个类中设计了一个纯虚函数

什么是纯虚函数?

纯虚函数最显著的特征:

        它们必须在继承类中重新声明函数(不要后面的=0,否则该派生类也不能实例化),而且它们在抽象类中往往没有定义。这样就声明了纯虚函数的类是一个抽象类。所以,用户不能创建类的实例,只能创建它的派生类的实例。(参考:https://zhuanlan.zhihu.com/p/270614081)

好了,看了上面的内容,做一下下面这道题吧

(C++ 2)以下关于纯虚函数的说法, 正确的是 ( )
A :声明纯虚函数的类不能实例化对象 B :声明纯虚函数的类是虚基类
C :子类必须实现基类的纯虚函数 D :纯虚函数必须是空函数

        

很多虚函数的调用必须通过指针或者引用来完成,

这是在运行阶段才能确定具体的调用行为,这导致了:

        第一,inline是在编译阶段就把调用处的代码替换成被调用的的函数实体,但是,那么此时调用处的代码无法被替换成虚函数的函数实体,所以虚函数不能设计成内联函数。

        第二,虚函数不能设计成静态函数

好了,看了上面的内容,做一下下面这道题吧

(C++ 3)关于虚函数的描述正确的是( )
A :派生类的虚函数与基类的虚函数具有不同的参数个数和类型 B :内联函数不能是虚函数
C :派生类必须重新定义基类的虚函数 D :虚函数可以是一个 static 型的函数

子类中从父类继承下来的那一部分和父类是不同的

C++可以多继承,多继承表名一个子类可以从多个类中继承数据和方法,

下面讨论如下场景:

        一个类从两个父类中进行继承,且这两个父类分别都有一个虚函数,记父类的名称分别为α,β,在子类中也定义了一个新的虚函数

那么这个子类中有三个部分:

        第一部分包括:α对应的数据和方法 和 α对应的虚函数表指针

        第二部分包括:β对应的数据和方法 和 β对应的虚函数表指针

        第三部分包括:专属于子类的数据和方法

虚函数表指针要等到该类在创建实例时执行初始化列表才能确定,这种行为也称为动态绑定

但是虚函数表是在编译阶段就已经由类的设计确定了的,虚函数表本质是一个函数指针数组

每个类都在编译期间分配了一个专属于这个类的函数指针数组,如果用这个类创建了多个对象,这些对象对应的函数指针数组是相同的

第一部分的虚表指针指向的虚表(也就是函数指针数组)中有两个元素

        第一个函数指针:指向α中定义的虚函数,

        第二个函数指针:指向子类中定义的新的虚函数

第二部分的虚表指针指向的虚表中有只有一个函数指针,指向α中定义的虚函数

好了,看了上面的内容,做一下下面这两道题吧

(C++ 4)假设D先继承B1,然后继承B2,B1和B2基类均包含虚函数,D类对B1和B2基类的 虚函数重写了,并且D类增加了新的虚函数,则()
A.D类对象模型中包含了3个虚表指针
B.D类对象有两个虚表,D类新增加的虚函数放在第一张虚表最后
C.D类对象有两个虚表,D类新增加的虚函数放在第二张虚表最后
D.以上全部错误
(C++ 5)关于虚表说法正确的是( )
A :一个类只能有一张虚表
B :基类中有虚函数,如果子类中没有重写基类的虚函数,此时子类与基类共用同一张虚表
C :虚表是在运行期间动态生成的
D :一个类的不同对象共享该类的虚表

虚函数表和虚函数表指针

虚函数表是一个函数指针数组,存放在常量区(或称代码段)中,

只要一个类或者其父类有虚函数存在,则一定存在至少一个虚函数表指针

虚函数表指针与类的位置关系,虚函数表指针是类实例化对象后最先开辟空间的成员变量

父类和子类虚函数表指针的关系

下面讨论如下场景,注意:下面的讨论和虚函数是否构成重写无关

        父类α中已经存在一个虚函数f, 且父类中没有继承其他任何的类,子类α1在类中重写了f,而且α1中不存在其他虚函数

父类创建的实例会存放虚表指针p1 和 父类所有的成员变量

子类创建的实例会分为两部分内存空间存放成员变量

        第一部分:虚表指针p2 和 父类所有的成员变量

        第二部分:子类所有成员变量

在这一场景中,p1和p2不同,子类和父类是两个不同的类,p1 != p2

好了,看了上面的内容,做一下下面这道题吧

(C++ 6)假设A 类中有虚函数, B 继承自 A B 重写 A中的虚函数,也没有定义任何虚函数,则( )
A A 类对象的前 4 个字节存储虚表地址, B 类对象前 4个字节不是虚表地址
B A 类对象和 B 类对象前 4个字节存储的都是虚基表的地址
C A 类对象和 B 类对象前 4个字节存储的虚表地址相同
D A 类和 B 类虚表中虚函数个数相同,但 A 类和 B类使用的不是同一张虚表

抽象类不能定义实例,但是可以有指向抽象类的指针

is-a 和 has-a

在继承中,子类是一个特殊的父类。在组合中,两个类的关系更可能是一种包含的关系

        比如,奔驰是一种汽车,此时奔驰类和汽车类的关系被称作 is-a 。

        再比如,汽车都有轮胎,此时汽车类和轮胎类的关系被称作 has-a。

在一个类的一开始加上final,可以使得这个类不能被继承

好了,看了上面的内容,做一下下面这道题吧

(C++ 7)关于继承说法正确的是 ( )
A :所有的类都可以被继承
B :Car(汽车)类和Tire(轮胎)类可以使用继承方式体现
C :继承是实现代码复用的唯一手段
D :狗是一种动物,可以体现出继承的思想

继承权限

class 关键字定义的类,如果有其他子类进行继承,可以不写继承方式,默认为 private 继承

struct 关键字定义的类,如果有其他子类进行继承,可以不写继承方式,默认为 public 继承

子类在继承了父类的私有成员之后,如果创建一个子类对象,子类对象存储的内存空间中会给这些父类中的私有成员专门开辟空间来存储,但是子类对象没有访问权限

好了,看了上面的内容,做一下下面这道题吧

(C++ 8) 下面关于继承权限说法正确的是 ( )
A:派生类在继承基类时,必须明确指定继承方式
B :class 定义的类,默认的访问权限是protected
C :struct 定义的类,默认的访问权限是public
D :子类没有继承基类私有的成员

重定义和函数重载

首先,在一个作用域中,不能定义两个相同名称的变量,也不能定义两个原型完全相同的函数,函数原型相同是指:两个函数的函数名和参数类型完全相同

子类继承了父类之后,子类的类域被划分成了两个作用域,两个作用域之间互不干扰

互不干扰是指可以有以下情况发生

        1. 两个作用域中分别定义两个变量,这两个变量的名称和类型相同,假设此变量名为 v

        2. 两个作用域中分别定义两个函数,这两个函数的名称完全相同,假设此函数名为 f

这两种情况有一种发生,都发生了重定义,注意2. 中对于参数列表和返回值的异同情况不作关注

此时创建一个子类对象,

        当子类对象访问 v 时,会默认访问子类新的作用域中的那个 v

        当子类对象调用 f 时,会默认访问子类新的作用域中的那个 f

如果想要子类旧的作用域中的 v 和 f,只需要在调用时在前面加上 父类名 ::

在一个作用域中,如果出现了两个同名函数,而且这两个同名函数的参数列表不同,那么此时发生了函数重载,注意此时对于函数返回值的一同情况不作关注

此时调用这个作用域中的函数,要根据函数调用时,参数列表的匹配情况确定调用哪个函数

好了,看了上面的内容,做一下下面这道题吧

(C++ 9) 关于同名隐藏的说法正确的是 ( )
A:同一个类中,不能存在相同名称的成员函数
B :在基类和子类中,可以存在相同名称但参数列表不同的函数,他们形成重载
C :在基类和子类中,不能存在函数原型完全相同的函数,因为编译时会报错
D :成员函数可以同名,只要参数类型不同即可,成员变量不能同名,即使类型不同

子类和父类中构造函数和析构函数的关系

针对子类对象在创建时,以及生命周期到了以后结束时这两个阶段分别进行讨论

子类对象在创建时,分两种情况

情况一:子类的初始化列表中没有关于父类构造的代码

        此时先调用父类的 默认 构造函数,再调用子类的构造函数

情况二:子类的初始化列表中存在关于创建父类对象的代码

        此时先调用父类的构造函数,再调用子类的构造函数

注意:此时调用父类的构造函数一定是通过父类的指针进行调用的

子类对象在销毁时,

此时先调用子类中的析构函数,再调用父类中的析构函数

注意:父类中的析构函数最好设计成虚函数,保证子类对象在销毁时,不会造成内存泄漏的问题

好了,看了上面的内容,做一下下面这道题吧

(C++ 10) 下面说法正确的是 ( )
A:派生类构造函数初始化列表的位置必须显式调用基类的构造函数,以完成基类部分成员的初始化
B :派生类构造函数先初始化子类成员,再初始化基类成员
C :派生类析构函数不会自动析构基类部分成员
D :子类构造函数的定义有时需要参考基类构造函数

静态成员的继承结果

静态成员函数也会被继承

静态成员变量在整个继承体系中只有一份,不属于任何对象,也就是说,在类实例化之后,调用sizeof(该类),结果不会考虑静态成员变量的大小

好了,看了上面的内容,做一下下面这两道题吧

(C++ 11) 下列哪个说法不正确 ( )
A:静态成员函数可以被继承
B :所有成员变量都可以被继承
C :基类的友元函数可以被继承
D :静态成员变量在整个继承体系中只有一份
(C++ 12) 关于基类与派生类对象模型说法正确的是 ( )
A:基类对象中包含了所有基类的成员变量
B :子类对象中不仅包含了所有基类成员变量,也包含了所有子类成员变量
C :子类对象中没有包含基类的私有成员
D :基类的静态成员可以不包含在子类对象中
E:   以上说法都不对

菱形继承需要注意的事项

菱形继承讨论的是如下场景:

class B {
public: 
    int b;
};

class C1: public B {
public: 
    int c1;
};

class C2: public B {
public: 
    int c2;
};

class D : public C1, public C2 {
public:
    int d;
};

此时D类对象开辟空间的示意图如下

此时由于有两个 b,造成了数据冗余和二义性的问题,要访问其中的一个 b,必须通过加上类名来确定使用哪个域中的 b

好了,看了上面的内容,做一下下面这道题吧

(C++ 13) 考虑如下场景,关于菱形继承,说法不正确的是( )

class B {
public: 
    int b;
};

class C1: public B {
public: 
    int c1;
};

class C2: public B {
public: 
    int c2;
};

class D : public C1, public C2 {
public:
    int d;
};

A:D总共占了20个字节
B :B中的内容总共在D对象中存储了两份
C :D对象可以直接访问从基类继承的 b 成员
D :菱形继承存在二义性问题,尽量避免设计菱形继承

---------------------------------------------------------------------------------------------------------------------------

以下是程序结果题

(倒反天罡) 程序结果题答案

一、0  1  2

二、A   B  C  D

三、C

四、B

好了,做一下下面的程序结果题吧

题目一:

题目二:

题目三:
题目四:

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

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

相关文章

Redis 实现 查找附近的人 功能

文章目录 概述Redis 中 Geospatial(地理位置)Demo例子总结 概述 使用 Redis 实现“查找附近的人”功能,通常会依赖 Redis 的 Geo(地理位置) 数据类型来存储用户的经纬度,并基于此进行地理范围查询。Redis …

最新价值5000元的V2M2引擎传奇源码2024BLUE升级版 团购

最新团购的V2M2引擎源码2024年BLUE升级版 特点优势是最新XE12编辑器,微端,各种自定义UI 无限仿GOM引擎功能 参考地址:最新价值5000元的V2M2引擎传奇源码2024BLUE升级版[原始团购版]_1234FCOM专注游戏工具及源码例子分享下载地址:BlueCodePXL…

.gitignore文件不起作用,GitHub和GitHubDeskTOP

问题:使用github或者github桌面版的时候配置的.gitignore文件不起作用,.gitignore文件是最新的,没有问题,只是提交的的时候Library、UserSettings这些文件还都一直在,尝试了大家说的清缓存等等方法,仍然没有…

代码随想录训练营Day28 | 39. 组合总和 | 40.组合总和II | 131.分割回文串

学习文档:代码随想录 (programmercarl.com) 学习视频:代码随想录算法公开课 | 最强算法公开课 | 代码随想录 (programmercarl.com) Leetcode 39. 组合总和 题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找…

springboot医院预约挂号系统

基于springbootvue实现的医院预约挂号系统 (源码L文ppt)4-085 4.1系统功能模块设计 医院预约挂号系统与数据分析系统在设计与实施时,采取了模块性的设计理念,把相似的系统的功能整合到一个模组中,以增强内部的功能…

谷粒商城踩坑

1.mysql表名大小写问题(P16) 问题描述:代码要求的是表名大写,但实际上数据库是小写的,就报错: 问题解决:未解决 mysql版本为5.7.44。网上有两种解决方式,但是都解决不了 1.1 解决方…

国药准字:您购药的可靠指南

益安宁丸为同溢堂药业有限公司所独家生产的一款中成药,在内地市场和港澳地区均有上市。 益安宁丸真品的唯一标准:无论港版还是内地版,包装盒必然有国药准字Z20063087标识,但凡没有国药准字标识的必为假药。

【C++】:bind绑定器和function函数对象机制

欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 文章目录 引言function函数对象function引入细讲function体验function在工程实践中的优势 模拟实现function函数对象机制bind绑定器基本语法示例1. 绑定普通函数2. 使用占位符3. 绑定成员函数4. 绑定 lambda 表…

【Android Studio】基础入门(一)—— 创建第一个 Android 项目

文章目录 前言一、创建项目二、启动模拟器三、运行程序 前言 Android Studio是谷歌官方推出的免费集成开发环境,专为安卓应用开发而设计,集成了代码编写、调试、界面设计及性能分析等多种强大功能,支持Java和Kotlin语言,极大提升了…

【vue2.7.16系列】手把手教你搭建后台系统__搭建开发环境(1)

安装开发环境 安装nodejs 使用nvm管理多个node版本。nvm-npm-nrm-配置介绍。本系列文章使用node14.19.3,安装好node后,npm也就安装好了,npm版本是v6.14.7 安装vue/cli 5.0.8 npm install -g vue/cli创建项目 vue create admin # 选项&am…

Compose 一个联系人索引列表实现

一、前言 该功能是一个左侧为字符索引列表,右侧为联系人列表的实现,点击左侧字符索引可以自动滑动到对应联系人条目。该功能代码实现绝大多数有通义灵码完成。实现效果如下: 关键代码 data class Contact(val name: String)class Contact…

unix中如何申请进程调度的优先级

一、前言 unix系统中,进程的调度是由内核决定的。在一个系统中,进程的优先级越高,表示其在一定时间中占用cpu的时间越久。本文将介绍unix系统如何修改以及获取进程的优先级。 二、nice值 nice值是unix系统中用于表征进程优先级的一个参数。…

MES系统中的正向追溯与反向追溯管理

随着制造业的日益发展,生产过程中的质量控制和管理变得尤为关键。MES系统作为一种实现车间生产管理和控制的重要工具,其追溯功能在生产过程中起着至关重要的作用。 一、MES系统概述 MES系统是一套面向制造企业车间执行层的生产信息化管理系统。它通过对…

药品名不得命名保健食品

益安宁丸为同溢堂药业有限公司所独家生产的一款中成药,在内地市场和港澳地区均有上市。

如何在算家云搭建MuseTalk(数字人)

一、 MuseTalk 简介 MuseTalk 是由腾讯团队开发的先进技术,它是一个实时的音频驱动唇部同步模型。该模型能够根据输入的音频信号,自动调整数字人物的面部图像,使其唇形与音频内容高度同步。 二、 MuseTalk 一键使用 基础环境最低要求说明&…

肺结节分割与提取系统(基于传统图像处理方法)

Matlab肺结节分割(肺结节提取)源程序,GUI人机界面版本。使用传统图像分割方法,非深度学习方法。使用LIDC-IDRI数据集。 工作如下: 1、读取图像。读取原始dicom格式的CT图像,并显示,绘制灰度直方图; 2、图像…

深圳市步步精科技有限公司荣获发明专利,彰显技术研发实力

2024年8月13日,深圳市步步精科技有限公司(BBJconn)正式获得了其新开发的防水连接器专利,授权公告号为CN 118352837 B。这项技术的突破标志着公司在连接器领域的持续创新,进一步巩固了其行业领先地位。 专利技术概述 此…

JavaScript 常用输出语句详解

目录 非 VIP 用户可前往公众号“前端基地”进行免费阅读 alert弹出警告框 Console 控制台输出 Document.write 直接在文档中显示 Prompt 弹出用户输入对话框 非 VIP 用户可前往公众号“前端基地”进行免费阅读 alert弹出警告框 在 JavaScript 中,alert可用于弹出…

Android Preference的使用以及解析

简单使用 values.arrays.xml <?xml version"1.0" encoding"utf-8"?> <resources><string-array name"list_entries"><item>Option 1</item><item>Option 2</item><item>Option 3</item&…

【权威出版|稳定检索】2024年信息学、网络与计算机应用技术国际会议(INCAT 2024)

2024 International Conference on Informatics, Networking, and Computer Application Technology 【1】大会信息 会议名称&#xff1a;2024年信息学、网络与计算机应用技术国际会议 会议简称&#xff1a;INCAT 2024 大会时间&#xff1a;请查看官网 大会地点&#xff1a;中…