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

在这里插入图片描述
💖作者:小树苗渴望变成参天大树🎈
🎉作者宣言:认真写好每一篇博客💤
🎊作者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关键在菱形继承的时候用过,里面的指针式虚基表的指针,指向的是存的偏移量的地方,在多态里面也使用了,里面存放的虚表指针,指向的是虚函数存放的地方

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单机环境下定时任务的基本原理和常见解决方案(二)之时间轮原理分析

单机环境下定时任务的基本原理和常见解决方案之时间轮原理分析 时间轮Netty时间轮使用Netty 时间轮 HashedWheelTimer 源码分析向时间轮里添加taskWorkerThread线程执行时间轮任务 多层时间轮总结 时间轮 生活中的时钟想必大家都不陌生&#xff0c;而时间轮的设计思想就是来源…

智能家居是否可与ChatGPT深度融合?

​ ChatGPT自2022年面世以来&#xff0c;已为亿万网民提供智能问答服务。然而我们是否曾想到&#xff0c;这一人工智能驱动的聊天机器人&#xff0c;是否可为智能家居赋能? 要实现ChatGPT与智能家居设备之间的无缝对话&#xff0c;单单依靠一台终端是远远不够的。ChatGPT必须…

【快应用】通用方法getBoundingClientRect的使用

【关键词】 快应用开发、通用方法、getBoundingClientRect 【背景】 快应用通用方法中提供了getBoundingClientRect方法来获取当前组件的布局位置&#xff0c;之前处理的快应用问题中&#xff0c;有个cp却把这种场景误解为可以获取到文字的宽度和高度&#xff0c;这是不合理的…

会议OA项目之会议发布(一)

目录 前言&#xff1a; 会议发布的产品原型图&#xff1a; 1.会议发布 1.1实现的特色功能&#xff1a; 1.2思路&#xff1a; 使用的数据库&#xff1a; 我们要实现多功能下拉框的形式选择可以参考原文档&#xff1a;https://hnzzmsf.github.io/example/example_v4.html#down…

Java-方法的使用

目录 一、方法的概念和使用 1.1方法的含义 1.2 方法的定义 1.3方法调用的执行过程 1.4实参和形参的关系 1.5没有返回值的方法 二、方法重载 2.1方法重载的含义 2.3 方法签名 三、递归 3.1 递归的概念 3.2递归的执行过程 3.3递归练习 一、方法的概念和使用 1.1方法的含义 方…

无符号数和有符号数的“bug”

1. 起因 在实现kmp算法时&#xff0c;出现了诡异的现象&#xff0c;看下面的代码&#xff1a; int KMP (const char *s, const char *t) {int lenS strlen (s);int lenT strlen (t);int next[lenT];get_next (next, t);int i 0;int j 0;while (i < lenS && j …

watch避坑,使用computed进行处理数据

业务场景&#xff1a;在vue中监听el-input 中的字数有没有超过60&#xff0c;如果超过60字时将60后面的字变为 “>>” 符号&#xff0c;以此实现预览苹果手机推送摘要场景。 错误&#xff1a;开始的逻辑是使用watch监听&#xff0c;检查length超过60直接 加上符号&#x…

深度学习:Pytorch最全面学习率调整策略lr_scheduler

深度学习&#xff1a;Pytorch最全面学习率调整策略lr_scheduler lr_scheduler.LambdaLRlr_scheduler.MultiplicativeLRlr_scheduler.StepLRlr_scheduler.MultiStepLRlr_scheduler.ConstantLRlr_scheduler.LinearLRlr_scheduler.ExponentialLRlr_scheduler.PolynomialLRlr_sched…

【六大锁策略-各种锁的对比-Java中的Synchronized锁和ReentrantLock锁的特点分析-以及加锁的合适时机】

系列文章目录 文章目录 系列文章目录前言一、六大"有锁策略"1. 乐观锁——悲观锁2. 轻量级锁——重量级锁3. 自旋锁——挂起等待锁4. 互斥锁——读写锁5. 可重入锁——不可重入锁6. 公平锁——非公平锁 二、Synchronized——ReentrantLockSynchronized的特点&#xf…

【C语言数据结构】模拟·顺序表·总项目实现

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

leetcode 376. 摆动序列

2023.7.28 本题思路是定义一个 direct变量记录上一次摆动是上坡还是下坡 。 然后在一个for循环中循环判断当前摆动和上一次摆动是否一致&#xff0c;如果不一致则视为一次摆动。 如果前后元素值相等得话&#xff0c;直接continue进入下一次循环。 下面看代码&#xff1a; clas…

leaftjs实现全国温度降水气压风速等值面风场洋流效果

实现内容 数据爬取、地图marker聚合、鼠标移动显示pop&#xff0c;风场&#xff0c;洋流&#xff0c;温度等值面、降水等值面、气压等值面、风速等值面&#xff0c;洋流方向、洋流流速展示、风场方向、风场风速展示&#xff0c;后期扩展小时预报&#xff0c;分钟预报、7天预报…

Matplotlib_概述_绘制图象

⛳绘制基础 在使用 Matplotlib 绘制图形时&#xff0c;其中有两个最为常用的场景。一个是画点&#xff0c;一个是画线。 pyplot 基本方法的使用如下表所示 方法名说明title()设置图表的名称xlabel()设置 x 轴名称ylabel()设置 y 轴名称xticks(x, ticks, rotation)设置 x 轴的…

(el-radio)操作:Element-plus 中 Radio 单选框改成垂直排列的样式操作与使用

Ⅰ、Element-plus 提供的Radio单选框组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供 Radio 组件情况&#xff1a; 其一、Element-ui 自提供的Radio代码情况为(示例的代码)&#xff1a; // Element-plus 自提供的代码&#xff1a; // 此时是使用了 ts 语言环境&a…

4.操作元素属性

4.1操作元素常用属性 ●通过 JS 设置/修改 标签元素属性&#xff0c;比如通过src更换图片 ●最常见的属性比如&#xff1a;href、 title、 src 等 ●语法: 对象.属性 值【示例】 // 1.获取元素 const pic document.querySelector( img ) // 2.操作元素 pic.src ./images/b…

商品库存管理系统设计与实现(Vue+SpringBoot+MySQL)

一、项目背景 当今&#xff0c;我国科技发展日新月异&#xff0c;各类企业迅速崛起&#xff0c;商品类型日益繁多&#xff0c;产品数量急剧增加&#xff0c;企业经营模式越来越多样&#xff0c;信息处理量不断加大&#xff0c;对库存管理提出了更高的要求。通过本系统&#xff…

LayUi 树形组件tree 实现懒加载模式,展开父节点时异步加载子节点数据

如题。 效果图&#xff1a; //lazy属性为true&#xff0c;点开时才加载 引用代码&#xff1a; <link href"~/Content/layui-new/css/layui.css" rel"stylesheet" /><form id"form" class"layui-form" style"margin-to…

数据库索引优化与查询优化——醍醐灌顶

索引优化与查询优化 哪些维度可以进行数据库调优 索引失效、没有充分利用到索引-一索引建立关联查询太多JOIN (设计缺陷或不得已的需求) --SQL优化服务器调优及各个参数设置 (缓冲、线程数等)–调整my.cnf数据过多–分库分表 关于数据库调优的知识点非常分散。不同的 DBMS&a…

YOLOv5:使用7.0版本训练自己的实例分割模型(车辆、行人、路标、车道线等实例分割)

YOLOv5&#xff1a;使用7.0版本训练自己的实例分割模型&#xff08;车辆、行人、路标、车道线等实例分割&#xff09; 前言前提条件相关介绍使用YOLOv5-7.0版本训练自己的实例分割模型YOLOv5项目官方源地址下载yolov5-7.0版源码解压目录结构 准备实例分割数据集在./data目录下&…

Rust vs Go:常用语法对比(七)

题图来自 Go vs Rust: Which will be the top pick in programming?[1] 121. UDP listen and read Listen UDP traffic on port p and read 1024 bytes into buffer b. 听端口p上的UDP流量&#xff0c;并将1024字节读入缓冲区b。 import ( "fmt" "net&qu…