【C++】-多态的经典题目

news2024/11/16 13:53:12

在这里插入图片描述
💖作者:小树苗渴望变成参天大树🎈
🎉作者宣言:认真写好每一篇博客💤
🎊作者gitee:gitee✨
💞作者专栏:C语言,数据结构初阶,Linux,C++ 动态规划算法🎄
如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧!

文章目录

  • 前言
  • 一、选择题
  • 二、程序题
  • 三、问答题


前言

今天博主专门出一篇继承和多态的相关的题目,为了就是让大家更好的进行掌握继承和多态,而且这里面有几题是比较坑的。我会一一给大家解释清楚的,话不多说,我们开始进入正文


一、选择题

  1. 下面哪种面向对象的方法可以让你变得富有(A )
    A: 继承 B: 封装 C: 多态 D: 抽象
  2. (D )是面向对象程序设计语言中的一种机制。这种机制实现了方法的定义与具体的对象无关,
    而对方法的调用则可以关联于具体的对象。
    A: 继承 B: 模板 C: 对象的自身引用 D: 动态绑定
  3. 面向对象设计中的继承和组合,下面说法错误的是?(C)
    A:继承允许我们覆盖重写父类的实现细节,父类的实现对于子类是可见的,是一种静态复用,也称为白盒复用
    B:组合的对象不需要关心各自的实现细节,之间的关系是在运行时候才确定的,是一种动态复用,也称为黑盒复用
    C:优先使用继承,而不是组合,是面向对象设计的第二原则
    D:继承可以使子类能自动继承父类的接口,但在设计模式中认为这是一种破坏了父类的封装性的表现
  4. 以下关于纯虚函数的说法,正确的是(A )
    A:声明纯虚函数的类不能实例化对象 B:声明纯虚函数的类是虚基类
    C:子类必须实现基类的纯虚函数 D:纯虚函数必须是空函数
  5. 关于虚函数的描述正确的是( C)
    A:派生类的虚函数与基类的虚函数具有不同的参数个数和类型 B:内联函数不能是虚函数
    C:派生类必须重新定义基类的虚函数 D:虚函数可以是一个static型的函数
  6. 关于虚表说法正确的是( D)
    A:一个类只能有一张虚表
    B:基类中有虚函数,如果子类中没有重写基类的虚函数,此时子类与基类共用同一张虚表
    C:虚表是在运行期间动态生成的
    D:一个类的不同对象共享该类的虚表
  7. 假设A类中有虚函数,B继承自A,B重写A中的虚函数,也没有定义任何虚函数,则( C)
    A:A类对象的前4个字节存储虚表地址,B类对象前4个字节不是虚表地址
    B:A类对象和B类对象前4个字节存储的都是虚基表的地址
    C:A类对象和B类对象前4个字节存储的虚表地址相同
    D:A类和B类虚表中虚函数个数相同,但A类和B类使用的不是同一张虚表

二、程序题

#include<iostream>
using namespace std;
class A{
public:
	  A(char *s) { cout<<s<<endl; }
	 ~A(){}
};

class B:virtual public A
{
public:
	 B(char *s1,char*s2):A(s1) { cout<<s2<<endl; }
};

class C:virtual public A
{
public:
	 C(char *s1,char*s2):A(s1) { cout<<s2<<endl; }
};

class D:public B,public C
{
public:
 	D(char *s1,char *s2,char *s3,char *s4):B(s1,s2),C(s1,s3),A(s1)
	 { cout<<s4<<endl;}
};
int main() {
	 D *p=new D("class A","class B","class C","class D");
 	delete p;
 return 0;
}

A:class A class B class C class D B:class D class B class C class A
C:class D class C class B class A D:class A class C class B class D

这题是非常的坑的,我们发现这是一个菱形继承,而且使用的virtual解决了数据冗余和二义性的,我们重复的数据就是基类里面的,现在我们的基类的里面的内容本来在B里面和C里面都有,现在在公共的地方,所以此时的问题就是就变成了,我们A的构造函数调用几次的问题,因为是我们创建d对像,所以我们是D类的构造函数去调用A的构造函数,而B,C类中关于A类的构造函数那一部分就失效了,先进行父类的构造在进行子类的构造,先继承的先构造,所以此题的选择是A

但是B,C构造函数里面的调用A的构造函数不能去掉,因为B,C类会单独创建对象也要使用

class Base1 {  public:  int _b1; };
class Base2 {  public:  int _b2; };
class Derive : public Base1, public Base2 { public: int _d; };
int main(){
	 Derive d;
	 Base1* p1 = &d;
	 Base2* p2 = &d;
	 Derive* p3 = &d;
 return 0;
}

A:p1 == p2 == p3 B:p1 < p2 < p3 C:p1 == p3 != p2 D:p1 != p2 != p3

这题在之前也有在之前也有对应的暗示,我们来画一个图来理解,因为不是多态,就是普通调用
在这里插入图片描述
此题的正确答案就是C

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

A: A->0 B: B->1 C: A->1 D: B->0 E: 编译出错 F: 以上都不正确

这题我们要了解多态的调用,虚函数重写的本质什么,构成多态的条件是什么
这题构成多态吗?

首先我们看符不符合
第一点:构不构成虚函数的重写
我们看到fun的父类加了virtual子类加不加无所谓,也符合三同,我们的参数列表只要求类型一样就行了,第一点是满足了
第二点:基类的指针或者引用去调用
我们发现先通过调用fun是通过test去调用,而test虽然是虚函数但是没有重写,但继承到子类B的虚表里面的了,我们创建一个子类对象的指针,去调用test也是调用父类的,此时的this指针就是父类的,然后再去调用fun,就相当于this->fun,此时就是使用了基类的指针去调用虚函数,这个条件也满足了

通过上面两点的分析我们知道构成多态,我们p是指向子类对象的,按道理答案是D,但是这题却不是的,因为我们子类是重写了虚函数的定义,使用虚函数的头,定义使用自己的,所以答案是B,现实中没人这么设计,好好的吧参数给的值不一样干嘛呢,没什么意义。

三、问答题

  1. 什么是多态?

现在从两点回答1.静态的多态(函数重载)2.动态的多态(继承中的虚函数重写),两种都是更方便和灵活的多种形态的调用

  1. 多态的实现原理?

第一种是靠函数名修饰规则,第二种是虚函数表

  1. inline函数可以是虚函数吗?

答案是可以的,只是inline的特性就被忽略了,优先是虚函数。

  1. 静态成员可以是虚函数吗?

答:不能,编译时强制报错,不允许这样的语法存在因为静态成员函数没有this指针,使用类型::成员函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。

  1. 构造函数可以是虚函数吗?

答:不能,因为对象中的虚函数表指针是在构造函数初始化列表
阶段才初始化的,是在构造的时候有了虚函数表指针,然后再走初始化列表,构造在前,虚表指在后,所以不能

  1. 对象访问普通函数快还是虚函数更快?

答:首先如果是普通对象,是一样快的。如果是指针对象或者是引用对象,则调用的普通函数快,因为构成多态,运行时调用虚函数需要到虚函数表中去查找。

  1. 虚函数表是在什么阶段生成的

答:虚函数表是在编译阶段就生成的,一般情况下存在代码段(常量区)的。

注意:virtual关键在菱形继承的时候用过,里面的指针式虚基表的指针,指向的是存的偏移量的地方,在多态里面也使用了,里面存放的虚表指针,指向的是虚函数存放的地方

今天的题目分享就到这里了,大家下去自己去理解一下吧
请添加图片描述

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

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

相关文章

解密C++多态机制:发挥对象的多样性,实现更加智能的程序设计

目录 一.多态1.多态的用处2.多态的实现3.虚函数4.override 和 final5.重载重写与重定义6.虚函数表 一.多态 1.多态的用处 众所周知C语言的三大特性&#xff1a;封装、多态、继承。其中多态就是去完成某个行为&#xff0c;但是会根据不同的对象产生不同的状态&#xff0c;所以…

Windows SMB 共享文件夹 排错指南

1 排错可能 是否系统名称为全英文格式 如果不是则 重命名 根据如下排错可能依次设置 1&#xff0c;在运行里面输入"secpol.msc"来启动本地安全设置&#xff0c;\ 然后选择本地策略–>安全选项 -->网络安全LAN 管理器身份验证级别&#xff0c;\ “安全设置”…

操作系统知识点总结

操作系统知识点总结: 第一章:操作系统概述 1.1操作系统的概念: ​ 操作系统是一种系统软件&#xff0c;与其他系统软件和应用软件不同&#xff0c;它有自己的基本特征。它的四大基本特征也就是并发&#xff0c;共享&#xff0c;虚拟&#xff0c;异步。 1.2操作系统的特征(四大…

前端开发信息套路:信息是如何传值

文章目录 前言信息组件化的难点&#xff1a;组件信息流通信息流通信息流通分类通知直接调用回调函数发布订阅全局缓存使用建议 总结 前言 作为一个写了好几个月的Uniapp小程序的打工狗&#xff0c;我总结了一下在前端中信息是如何传递的&#xff0c;得出了一个比较标准化的信息…

thinkphp6 验证码验证结果失败,可能是session开启位置错了!!!

搞了一下下午&#xff0c;始终提示验证码不正确 然后百度得到的结果都是&#xff1a;开启session&#xff0c;但是我开启了就是管用 <?php // 全局中间件定义文件 return [// 全局请求缓存// \think\middleware\CheckRequestCache::class,// 多语言加载// \think\middle…

【人人都看懂的漫画算法】边打扑克边学插入排序算法,彻底搞懂时间复杂度

博主&#xff1a;爱码叔 个人博客站点&#xff1a; icodebook.com 公众号&#xff1a;漫话软件设计 微博&#xff1a;程序员涛哥 专注于软件设计与架构、技术管理。擅长用通俗易懂的语言讲解技术。对技术管理工作有自己的一定见解。文章会第一时间首发在个站上&#xff0c;欢迎…

如何评判算法好坏?复杂度深度解析

如何评判算法好坏&#xff1f;复杂度深度解析 1. 算法效率1.1 如何衡量一个算法好坏1.2 算法的复杂度 2 时间复杂度2.1 时间复杂度的概念2.1.1 实例 2.2 大O的渐进表示法2.3 常见时间复杂度计算举例 3 空间复杂度4 常见复杂度对比5 结尾 1. 算法效率 1.1 如何衡量一个算法好坏 …

Android Studio import的代码报红提示找不到,但正常编译运行

Android Studio import的代码报红提示找不到&#xff0c;但正常编译运行 解决方案&#xff1a; &#xff08;1&#xff09;关闭退出Android Studio。 &#xff08;2&#xff09;删掉当前工程项目目录下的.idea和.gradle文件夹。 &#xff08;3&#xff09;Invalidate Caches…

uni-app之微信小程序实现‘下载+保存至本地+预览’功能

目录 一、H5如何实现下载功能 二、微信小程序实现下载资源功能方面与H5有很大的不同 三、 微信小程序实现文件&#xff08;doc,pdf等格式&#xff0c;非图片&#xff09;下载&#xff08;下载->保存->预览&#xff09;功能 四、图片预览、保存、转发、收藏&#xff1…

MMdetection框架速成系列 第07部分:数据增强的N种方法

MMdetection框架实现数据增强的N种方法 1 为什么要进行数据增强2 数据增强的常见误区3 常见的六种数据增强方式3.1 随机翻转&#xff08;RandomFlip&#xff09;3.2 随机裁剪&#xff08;RandomCrop&#xff09;3.3 随机比例裁剪并缩放&#xff08;RandomResizedCrop&#xff0…

F12开发者工具的简单应用

目录 elements 元素 1、元素的定位和修改 2、UI自动化应用 console 控制台 sources 源代码 network 网络 1、定位问题 2、接口测试 3、弱网测试 performance 性能 memory 存储 application 应用 recorder 记录器 界面展示如下&#xff08;设置中可以切换中英文&am…

云共享平台:助力企业数字化转型的利器

随着互联网技术的不断发展&#xff0c;云共享平台正在成为企业发展必不可少的工具之一。那么&#xff0c;云共享平台到底为企业带来了哪些助力呢&#xff1f; 1. 提高效率 云共享平台可以极大地提高企业的工作效率。传统的企业数据管理通常都需要人工操作&#xff0c;而且往往…

redis数据库与主从复制

目录 一 基本操作 二 执行流程 三 reids持久化 四 rdb和aof持久化的过程 五 为什么会有内存碎片 六 redis组从复制 一 基本操作 set :存放数据 例如 set 键值 内容 set k kokoko k就是键值 kokoko就是内容 get:获取数据 例如 get k 就会出来 k对应的数据 keys 查询键…

【大数据之Flume】三、Flume进阶之Flume Agent 内部原理和拓扑结构

1 Flume事务 2 Flume Agent 内部原理 重要组件&#xff1a; 1、ChannelSelector&#xff08;选择器&#xff09;   ChannelSelector 的作用就是选出 Event 将要被发往哪个 Channel。   &#xff08;1&#xff09;Replicating ChannelSelector&#xff08;复制或副本&#x…

Python实现HBA混合蝙蝠智能算法优化LightGBM回归模型(LGBMRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝙蝠算法是2010年杨教授基于群体智能提出的启发式搜索算法&#xff0c;是一种搜索全局最优解的有效方法…

「前缀和以及差分数组」

文章目录 1 前缀和数组1.1 题解1.2 Code1.3 结果 2 二维矩阵的前缀和数组2.1 题解2.2 Code2.3 结果 3 差分数组 1 前缀和数组 适用于快速频繁的计算一个索引区间内的元素之和&#xff0c;核心思想就是使用一个前缀和数组&#xff0c;然后使用前缀和数组的两个元素之差&#xf…

Postman(一)--接口测试知识准备

1.0 前言 ​ 应用程序编程接口&#xff08;Application Programming Interface, API&#xff09;是这些年来最流行的技术之一&#xff0c;强大的Web应用程序和领先的移动应用程序都离不开后端强大的API。API技术的应用给系统开发带来了便利&#xff0c;但也对测试人员提出了更…

【AGI】Copilot AI编程辅助工具安装教程

GitHub和OpenAI联合为程序员们送上了编程神器——GitHub Copilot。 但是&#xff0c;Copilot目前不提供公开使用&#xff0c;需要注册账号通过审核&#xff0c;我也提交了申请&#xff1a;这里第一期记录下&#xff0c;开启教程&#xff0c;欢迎大佬们来讨论交流。

Jmeter性能测试:高并发分布式性能测试

一、为什么要进行分布式性能测试 当进行高并发性能测试的时候&#xff0c;受限于Jmeter工具本身和电脑硬件的原因&#xff0c;无法满足我们对大并发性能测试的要求。 基于这种场景下&#xff0c;我们就需要采用分布式的方式来实现我们高并发的性能测试要求。 二、分布式性能测…

微信云开发管理工具入门教程

前言 微信云开发管理工具是是什么&#xff1f; 提供了一套云开发的后台管理工具&#xff0c;并且提供低代码开发工具&#xff0c;开发者可基于低代码工具&#xff0c;连接到业务数据库&#xff0c;拖拽组件生成前端UI&#xff0c;从而定制各类管理端应用。 在这里肯定有同学会…