【C++】多态练习题(面试常考)

学习之前,建议观看:【C++】多态:深度剖析(多态、虚函数、抽象类、底层原理)_c++ 多态和虚函数,虚函数的实现原理-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/2301_80555259/article/details/142178677?spm=1001.2014.3001.5501


一.概念题

1.关于虚函数说法正确的是( )

A.被virtual修饰的函数称为虚函数

B.虚函数的作用是用来实现多态

C.虚函数在类中声明和类外定义时候,都必须加虚拟关键字

D.静态虚成员函数没有this指针

答案:B

对于A,必须是被virtual修饰的成员函数;

对于C,虚函数不能在类外定义;

对于D,不存在静态虚函数这种说法,static和virtual不能同时修饰一个成员函数

2.关于不能设置成虚函数的说法正确的是( )

A.友元函数可以作为虚函数,因为友元函数出现在类中

B.成员函数都可以设置为虚函数

C.静态成员函数不能设置成虚函数,因为静态成员函数不能被重写

D.析构函数建议设置成虚函数,因为有时可能利用多态方式通过基类指针调用子类析构函数

答案:D

对于A,友元函数不属于成员函数,因此友元函数不能被修饰为虚函数;

对于B,静态成员函数不可以设置为虚函数;

对于C,原因错误,静态成员函数之所以不能设置为虚函数是因为 静态成员函数属于整个类,没有this指针,从而无法利用this指针找到类中的虚表指针,从而找到虚表中的虚函数地址

3.关于多态,说法不正确的是( )

A.C++语言的多态性分为编译时的多态性和运行时的多态性

B.编译时的多态性可通过函数重载实现

C.运行时的多态性可通过模板和虚函数实现

D.实现运行时多态性的机制称为动态绑定

答案:C ,运行时的多态性不能使用模板实现,模板属于编译时多态

4.要实现多态类型的调用,必须( )

A.基类和派生类原型相同的函数至少有一个是虚函数即可

B.假设重写成功,通过指针或者引用调用虚函数就可以实现多态

C.在编译期间,通过传递不同类的对象,编译器选择调用不同类的虚函数

D.只有在需要实现多态时,才需要将成员函数设置成虚函数,否则没有必要

答案:D

对于A,只能是基类中为虚函数;

对于B,完整应该是 通过基类(父类)的指针或者引用来调用虚函数;

对于C,多态是运行时多态,不是在编译期间。编译期间编译器主要是检查语法错误,此时无法得知基类指针具体指向哪个对象,只有在运行时,才知道指向的具体对象,从而调用其虚表中的函数,实现多态

5.关于重载、重写和重定义的区别说法正确的是( )【不定项选择】

A.重写和重定义都发生在继承体系中

B.重载既可以在一个类中,也可以在继承体系中

C.它们都要求原型相同

D.重写就是重定义

E.重定义就是重写

F.重写比重定义条件更严格

G.以上说法全错误

答案:A、F ,

对于B,重载的两个函数必须在同一作用域,不能在两个不同的类中;

对于C,重载要求函数名相同,参数不同。重写要求函数名,参数,返回值都必须相同,即原型相同。而重定义仅要求函数名相同;

对于D、E ,很明显不相同,下图是具体区别图

6. 关于抽象类和纯虚函数的描述中,错误的是 ( )

A.纯虚函数的声明以“=0;”结束

B.有纯虚函数的类叫抽象类,它不能用来定义对象

C.抽象类的派生类如果不实现纯虚函数,它也是抽象类

D.纯虚函数不能有函数体

答案:D,纯虚函数可以拥有函数体,只是这意义不大,需要被重写

7.关于虚表说法正确的是( )

A.一个类只能有一张虚表

B.基类中有虚函数,如果子类中没有重写基类的虚函数,此时子类与基类共用同一张虚表

C.虚表是在运行期间动态生成的

D.一个类的不同对象共享该类的虚表

答案:D

对于A,若一个类继承了多个父类,那么将拥有多个虚表

对于B,并不是共用一张虚表,而是子类的虚表中依旧是基类的虚表内容,还没被覆盖而已

对于C,虚表是在编译时生成的

 8.假设D类先继承B1,然后继承B2,B1和B2基类均包含虚函数,D类对B1和B2基类的虚函数重写了,并且D类增加了新的虚函数,则:( )

A.D类对象模型中包含了3个虚表指针

B.D类对象有两个虚表,D类新增加的虚函数放在第一张虚表最后

C.D类对象有两个虚表,D类新增加的虚函数放在第二张虚表最后

D.以上全部错误

答案:B , D继承了两个父类,故有两个虚表指针,同时,子类新增的虚函数会只会放在第一个虚表的最后,其他父类虚表不需要储存

二.程序分析题

1.以下哪项说法时正确的( )

A.基类和子类的f1函数构成重写

B.基类和子类的f3函数没有构成重写,因为子类f3前没有增加virtual关键字

C.基类引用引用子类对象后,通过基类对象调用f2时,调用的是子类的f2

D.f2和f3都是重写,f1是重定义

class A
{
public:void f1(){cout<<"A::f1()"<<endl;}virtual void f2(){cout<<"A::f2()"<<endl;}virtual void f3(){cout<<"A::f3()"<<endl;}
};class B : public A
{
public:virtual void f1(){cout<<"B::f1()"<<endl;}virtual void f2(){cout<<"B::f2()"<<endl;}void f3(){cout<<"B::f3()"<<endl;}
};

答案:D

对于A,由于父类A中f1没有添加关键字virtual,不构成重写

对于B,虽然子类B中f3没有关键字virtual,但是继承了父类中该函数的虚函数性质,因此仍然构成重写,但是这种写法是不规范,不推荐的

对于C,“通过基类对象调用f2”是错误的,直接通过对象来进行调用函数,就不会通过虚表以多态的形式调用了(其实这个选项有点抠字眼,前一句引用很容易误导)

2.下面函数输出结果是( )

A.B::f()

B.A::f(),因为子类的f()函数是私有的

C.A::f(),因为强制类型转化后,生成一个基类的临时对象,pa实际指向的是一个基类的临时对象

D.编译错误,私有的成员函数不能在类外调用

class A
{
public: virtual void f(){cout<<"A::f()"<<endl;}
};class B : public A
{
private:virtual void f(){cout<<"B::f()"<<endl;}
};int main()
{A* pa = (A*)new B;pa->f();
}

答案:A

尽管该重写的函数是私有成员,但多态的本质是虚表中函数地址的覆盖,该虚函数在子类中重写后,子类虚表中该函数地址就被重写后的函数的地址覆盖,调用时,也是直接根据函数地址调用,因此能够成功调用private内的成员函数,编译成功,运行成功

3.以下程序输出结果是( )

A.1 0

B.0 1

C.0 1 2

D.2 1 0

E.不可预期

F. 以上都不对

class A
{
public:A() :m_iVal(0) { test(); }virtual void func() { std::cout << m_iVal << " "; }void test() { func(); }
public:int m_iVal;
};class B : public A
{
public:B() { test(); }virtual void func(){++m_iVal;std::cout << m_iVal << " ";}
};int main(int argc, char* argv[])
{A* p = new B;p->test();return 0;
}

答案:C

首先,new B子类时,要先调用父类的构造函数,再调用子类的构造函数。因此用0初始化了m_iVal并打印,而后调用子类的构造函数,此时父类已经构造完成,虚表也已经生成了,B调用继承来的test(),继承的test中的this是A*类型,即基类指针,满足多态的所有条件,因此调用子类的func,进行+1并打印,而后的p->test()再重复一次多态的过程,故最终结果为:

0 1 2

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

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

相关文章

解决 Macos下 Orbstack docker网络问题

两种解决方法&#xff0c;第一种开代理 参考 —— 但是我这一种没成功&#xff0c;第二种方法是换镜像源 { "registry-mirrors": ["http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn","https://mirrors.tencent.com&q…

《向量数据库指南》——Milvus 和 Fivetran 如何为 AI 构建基础

哈哈,说起 Milvus 和 Fivetran 如何为 AI 构建基础,这可真是个有意思的话题!来,让我这个向量数据库领域的“老司机”给你详细讲解一番,保证让你听得津津有味,还能学到不少干货! Milvus 和 Fivetran:AI 搜索解决方案的黄金搭档 在当今这个数据爆炸的时代,AI 已经成为…

使用MTVerseXR SDK实现VR串流

1、概述​ MTVerseXR SDK 是摩尔线程GPU加速的虚拟现实&#xff08;VR&#xff09;流媒体平台&#xff0c;专门用于从远程服务器流式传输基于标准OpenXR的应用程序。MTVerseXR可以通过Wi-Fi和USB流式将VR内容从Windows服务器流式传输到XR客户端设备, 使相对性能低的VR客户端可…

【10000字pandas数据可视化超全笔记整理】Numpy Pandas | 常用API介绍 | 缺失值处理 matplotlib数据可视化介绍

文章目录 Numpy 部分NumPy的数组类被称作ndarray&#xff0c;通常被称作数组。属性创建方法内置函数运算基本运算矩阵运算 Pandas部分总述Serise 对象创建属性方法运算 DataFrame属性索引操作添加删除插入列 保存读取文件保存读取 数据加载分组聚合语法格式: 基本绘图 数据组合…

Vue3 Typescript 前端页面5min后无操作自动退出至登录页面

效果图&#xff1a; 前端页面5min无操作&#xff0c;弹出弹窗提示用户系统将在30s后退出&#xff0c;30s后系统自动退出至登录页面。 <template><div><div class"f-z-20-px">{{ remainTime }}秒后无操作将退出</div><el-dialogtitle&quo…

C语言 getchar 函数完全解析:掌握字符输入的关键

前言 在C语言中&#xff0c;getchar 是一个非常实用的函数&#xff0c;用于从标准输入流&#xff08;通常是键盘&#xff09;读取单个字符。这对于处理文本输入非常有用&#xff0c;尤其是在需要逐个字符处理的情况下。本文将深入探讨 getchar 函数的用法和特点&#xff0c;并…

【Ubuntu】git

文章目录 1.配置SSH key2. 基础知识操作命令1分支branch 如果对git命令使用不熟悉&#xff0c;推荐一个非常棒的git在线练习工具 Learn Git Branching。 https://m.runoob.com/git/git-basic-operations.html 1.配置SSH key ssh-keygen -t rsa -C "YOUR EMAIL"完成…

软考中级网络规划设计师已过,分享一些备考心得

据说通过率只有15%左右&#xff0c;蛮低&#xff0c;但我还是一次过了。 其实参加考试的人不多&#xff0c;考场上来的人也就一半&#xff0c;很多人报名之后弃考了。。。所以我觉得最重要的还是坚持。 网规不像高项是热门科目&#xff0c;参考资料很多&#xff0c;自学的话某…

SpringBoot3响应式编程全套-Reactor核心

目录 传送门前言一、前置知识1、Lambda2、Function3、StreamAPI4、Reactive-Stream 二、Reactor1、快速上手1.1、介绍1.2、依赖 2、响应式编程2.1、阻塞是对资源的浪费2.2、异步可以解决问题吗&#xff1f;2.3、从命令式编程到响应式编程 三、核心特性1、Mono和Flux2、subscrib…

在 AI 大模型时代,了解 Agentic RAG 的核心理念至关重要

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ Agentic RAG&#xff0c;即基于智能体的检索增强生成技术&#xff0c;融合了 AI Agent 与 RAG 技术的优势。该技术通过集成 AI Agent&#xff0c;显著提升了 RAG 系统的智能水平与自主能力&#xff0c;…

1.7 编码与调制

欢迎大家订阅【计算机网络】学习专栏&#xff0c;开启你的计算机网络学习之旅&#xff01; 文章目录 前言前言1 基本术语2 常用的编码方法2.1 不归零编码2.2 归零编码2.3 反向归零编码2.4 曼彻斯特编码2.5 差分曼彻斯特编码 3 常用的调制方法3.1 调幅&#xff08;AM&#xff09…

Linux网络操作命令与函数全面总结

1. 引言 Linux作为服务器和开发平台&#xff0c;网络操作是其核心功能之一。本文旨在全面总结Linux系统中的网络操作方法&#xff0c;包括命令行工具和编程接口&#xff0c;帮助读者深入理解Linux网络管理的机制。 2. 命令行工具 2.1 ping 命令 ping 命令用于测试网络连接和…

【初阶数据结构】详解插入排序 希尔排序(内含排序的概念和意义)

文章目录 前言1. 排序的概念及其应用1.1 排序的概念1.2 排序的应用 2. 插入排序2.1 基本思想2.2 插入排序的代码实现2.3 插入排序算法总结 3. 希尔排序3.1 基本思想3.2 希尔排序的代码实现3.3 希尔排序的特征总结 前言 初级数据结构系列已经进入到了排序的部分了。相信大家听到…

DolphinScheduler 资源中心无法上传大文件

服务&#xff1a;dolphinscheduler 版本&#xff1a;v3.16 问题描述&#xff1a;资源中心-文件管理中使用文件上传是出现中断或上传失败 排除思路&#xff1a; 测试小文件或其他类型文件时是否正常&#xff1b;F12查看接口调用成功以及失败时的对比&#xff0c;发现接口调用…

内核级理解套接字和全连接队列

一、全连接队列 listen 函数第二个参数 backlog 是输入全连接队列的长度&#xff0c;一般不会太大。那如何理解全连接队列呢&#xff1f; 首先三次握手建立连接的过程和服务器是否 accept 无关&#xff0c;accept 的本质就是把已经建立的连接以文件描述符的形式返回。 那么在…

[含文档+PPT+源码等]精品大数据项目-基于Django实现的高校图书馆智能推送系统的设计与实现

大数据项目——基于Django实现的高校图书馆智能推送系统的设计与实现背景&#xff0c;可以从以下几个方面进行详细阐述&#xff1a; 一、信息技术的发展背景 随着信息技术的飞速发展和互联网的广泛普及&#xff0c;大数据已经成为现代社会的重要资源。在大数据背景下&#xf…

言语理解(3)

如果选项中填写的第一句话是文言文&#xff0c;那么尤其要注意它后面的第一句话 D B 要注意要填写的句子后面最近的一句话 文艺和时代和文章中的主题词&#xff0c;B和D的区别就是文艺带动时代向前发展&#xff0c;D是文艺和时代互相影响&#xff0c;从全文可知是文艺影响时代带…

墙绘艺术市场的数字化转型:SpringBoot案例

1 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。这样的大环境让那些止步不前&#…

常州威雅学校:欢迎探访校园,共赴全人教育之旅!

自2012年创校起&#xff0c;我们践行着“每一个孩子都卓越”的全人教育理念&#xff0c;见证了常州威雅发展至今天的方兴未艾。在岁月不居&#xff0c;时节如流间&#xff0c;我们用点点滴滴的耕耘&#xff0c;为学生的成长穿针引线&#xff0c;也在学校建设中精益求精。 一百次…

计算机毕业设计 服装生产信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…