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

news2024/11/19 10:16:02

学习之前,建议观看:【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.coloradmin.cn/o/2181948.html

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

相关文章

echarts X轴出现小数点问题解决方案

问题描述 当X轴数据较小时&#xff0c;X轴的坐标会用小数点将数据撑开&#xff0c;使其均匀显示&#xff0c;如下图所示&#xff1a; 因业务需要不希望出现小数点&#xff0c;该怎么解决呢&#xff1f; 查找一番&#xff0c;解决方案如下&#xff1a; xAxis: {minInterval:…

2-108 基于matlab的模板匹配法实现车牌识别

基于matlab的模板匹配法实现车牌识别&#xff0c;包含完整的字符库和案例车牌。选择待识别车牌&#xff0c;对车牌图像进行边缘检测、腐蚀、平滑、定位彩色、滤波、最小化区域等一系列操作&#xff0c;分割出字符区域&#xff0c;并与全字符模板库比较&#xff0c;得到最终的车…

【LeetCode每日一题】——95.不同的二叉搜索树 II

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 回溯 二【题目难度】 中等 三【题目编号】 95.不同的二叉搜索树 II 四【题目描述】 给你一…

NASA数据集:ATLAS/ICESat-2 L3B 每日和每月网格化海冰自由面高度,第 4 版

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Daily and Monthly Gridded Sea Ice Freeboard, Version 4 简介 ATLAS/ICESat-2 L3B Daily and Monthly Gridded Sea Ice Freeboard, Version 4数据是由NASA的ATLAS&#xff08…

idea.vmoptions 最佳配置

1. 推荐的 idea64.exe.vmoptions 配置&#xff1a; -Xms1024m -Xmx4096m -XX:ReservedCodeCacheSize512m -XX:UseG1GC -XX:SoftRefLRUPolicyMSPerMB50 -XX:CICompilerCount4 -XX:HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -Dsun.io.useCanonCachesfalse -Dj…

【React 】入门Day01 —— 从基础概念到实战应用

目录 一、React 概述 二、开发环境创建 三、JSX 基础 四、React 的事件绑定 五、React 组件基础使用 六、组件状态管理 - useState 七、组件的基础样式处理 快速入门 – React 中文文档 一、React 概述 React 是什么 由 Meta 公司开发&#xff0c;是用于构建 Web 和原生…

RabbitMQ的应用问题

一、幂等性保障 幂等性是数学和计算机科学中某些运算的性质, 它们可以被多次应⽤, ⽽不会改变初始应⽤的结果 数学上的幂等性&#xff1a; f(x)f(f(x)) |x| 数据库操作幂等性&#xff1a; 数据库的 select 操作. 不同时间两次查询的结果可能不同, 但是这个操作是符合幂等性…

MetaShape+CloudCompare的一些基本操作(一)

一、前言 由于要做一些小小的数据处理&#xff0c;要进行无人机影像的拼接&#xff0c;上网一搜发现metashape&#xff08;前photoscan&#xff09;很好用。由于一些影像涉及到未发布的论文和知识版权&#xff0c;所以进行了打码处理&#xff0c;请见谅&#xff01;&#xff01…

实验5 预备实验2-配置单个的路由器

配置单个的路由器 一、实验目的 此次试验目的是了解思科网络设备的配置基本特点及IOS命令基本操作方法。这些是配置思科设备的重要前提。 二、实验内容及结果 1、实验环境搭建 添加一个模块化的路由器&#xff0c;单击Packet Tracer 5.3的工作区中刚添加的路由器&#xff0c;…

【老生常谈、查漏补缺】SpringBoot接收参数的几种方式图文详解

前言 在实际开发过程中&#xff0c;我们经常会遇到各种不同的场景&#xff0c;需要从客户端接收不同的参数。Spring Boot 提供了多种方式来接收这些参数&#xff0c;使得我们的开发更加灵活便捷。这篇文章主要介绍了 SpringBoot 在接收参数的几种常用方式详解。随着前后端的分离…

如何从huggingface下载

我尝试了一下若干步骤&#xff0c;莫名奇妙就成功了 命令行代理 如果有使用魔法上网&#xff0c;可以使用命令行代码&#xff0c;解决所有命令行连不上外网的问题&#xff1a; #配置http git config --global http.proxy 127.0.0.1:xxxx git config --global https.proxy 127…

Redis入门第二步:Redis数据类型详解

摘要&#xff1a; 欢迎继续跟随《Redis新手指南&#xff1a;从入门到精通》专栏的步伐&#xff01;在本文中&#xff0c;我们将深入探讨Redis支持的各种数据类型&#xff0c;这些类型是Redis强大功能的核心。通过学习不同的数据类型&#xff0c;你将能够根据具体的应用需求选择…

Sping源码:三级缓存

目录 一、概念1、三级缓存的作用2、循环依赖的含义 二、代码1、代码下载2、文件功能介绍3、源码分析3.1、找到获取A对象的位置&#xff0c;打断点进行debug操作3.2、一步步找到在A对象中注入B对象的位置3.3、一步步找到B对象注入A对象的位置3.4、往下找到通过三级缓存解决循环依…

综合绩效考核系统源码,三级医院绩效管理系统源码,基于springboot、mybaits+avue技术开发,支持项目二开。

医院综合绩效考核系统源码 商业项目源码&#xff0c;支持二次开发 采用多维度综合绩效考核的形式&#xff0c;针对院内实际情况分别对工作量、KPI指标、科研、教学、管理等进行全面考核。医院可结合实际需求&#xff0c;对考核方案中各维度进行灵活配置&#xff0c;对各维度的权…

MPS---MP87180芯片layout设计总结

今天是一个特殊的日子&#xff0c;十一节前最后一天了&#xff0c;小编我还在迪拜出差中&#xff0c;而且组内也就剩下我一个人在值班了&#xff0c;来自韩国首尔的测试同事杰总提前一周就回韩国了&#xff0c;EE同事龟田一郎桑也是提前三天回日本东京去了&#xff0c;只有我最…

Brave编译指南2024 MacOS篇-构建与运行(六)

引言 在上一篇文章中&#xff0c;我们成功初始化了Brave浏览器的构建环境。现在&#xff0c;我们进入了这个编译指南的核心部分&#xff1a;实际构建Brave浏览器并运行它。这个过程将把我们之前准备的所有源代码和依赖项转化为一个可运行的浏览器实例。 1. 编译Brave浏览器 …

C++—vector的使用及实现

✨✨ 欢迎大家来到小伞的大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 小伞的主页&#xff1a;xiaosan_blog 1.vector 1.1vector的介绍 cplusplus.com/reference/vector/vector/ 1.2vecto…

wpa_cli支持EAP-TTLS认证运行设计

wpa_cli支持EAP-TTLS认证运行设计 1 输入 1.1 启动wpa_supplicant 和 wpa_cli 在OpenHarmony开发板或华为开发机的命令行中输入 wpa_supplicant -Dnl80211 -c/data/service/el1/public/wifi/wpa_supplicant/wpa_supplicant.conf -gabstract:/data/service/el1/public/wifi/s…

【D3.js in Action 3 精译_026】3.4 小节 DIY 实战:基于 Mocha 在浏览器客户端测试 D3 线性比例尺

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可…

力扣(leetcode)每日一题 2286 以组为单位订音乐会的门票 | 线段树

2286. 以组为单位订音乐会的门票 题干 一个音乐会总共有 n 排座位&#xff0c;编号从 0 到 n - 1 &#xff0c;每一排有 m 个座椅&#xff0c;编号为 0 到 m - 1 。你需要设计一个买票系统&#xff0c;针对以下情况进行座位安排&#xff1a; 同一组的 k 位观众坐在 同一排座…