这15道C++多态宝藏题及题解,值得瞧一瞧的喔!

news2024/9/28 16:52:54

在这里插入图片描述

这一章主要是对C++多态——点我可以了解章节的具体应用,接下来一道一道的来分析:👇👀

1. 关于虚函数说法【正确】的是( B)
A.被virtual修饰的函数称为虚函数
B.虚函数的作用是用来实现多态
C.虚函数在类中声明和类外定义时候,都必须加虚拟关键字
D.静态虚成员函数没有this指针

1:解析:
A:对应知识点是非成员函数不能写为虚函数。因此被virtual修饰的成员函数才是虚函数。
B:虚函数的主要作用没得说了,就是为实现多态而生的。
C:简单来说,virtual关键字只能在声明时加,在类外实现不能加。
在这里插入图片描述
D:static和virtual是不能同时使用。
在这里插入图片描述

2.关于不能设置成虚函数的说法【正确】的是( D)
A.友元函数可以作为虚函数,因为友元函数出现在类中
B.成员函数都可以设置为虚函数
C.静态成员函数不能设置成虚函数,因为静态成员函数不能被重写
D.析构函数建议设置成虚函数,因为有时可能利用多态方式通过基类指针调用子类析构函数

2:解析:
A:知识点也是只有成员函数才能写为虚函数,因为友元函数不是成员函数
B:不是所有的成员函数都可以设置为虚函数,静态成员函数是不可以定义为虚函数的。
C:.静态成员函数与具体对象无关,属于整个类,核心关键是没有隐藏的this指针,可以通过类名::[成员函数名] 直接调用,此时没有this无法拿到虚表,就无法实现多态,因此不能设置为虚函数。
D:在此处尤其是父类的析构函数强烈建议设置为虚函数,因为在动态释放父类指针所指向的子类时,能够达到析构的多态。

3.关于多态,说法不正确的是(C )
A.C++语言的多态性分为编译时的多态性和运行时的多态性
B.编译时的多态性可通过函数重载实现
C.运行时的多态性可通过模板和虚函数实现
D.实现运行时多态性的机制称为动态绑定

3:解析:
C:模版是在编译时确定的属于编译时多态,故错误了。

4.要实现多态类型的调用,必须(C )
A.基类和派生类原型相同的函数至少有一个是虚函数即可
B.假设重写成功,通过指针或者引用调用虚函数就可以实现多态
C.在编译期间,通过传递不同类的对象,编译器选择调用不同类的虚函数
D.只有在需要实现多态时,才需要将成员函数设置成虚函数,否则没有必要

4:解析:
A:前提条件是要父类的那个函数要是虚函数才可以。
B:必须通过父类的指针或引用来调用虚函数,才可以实现多态。
C:不是在编译期,而应该在运行期间,编译期间,编译器主要检测代码是否违反语法规则,此时无法知道基类的指针或者引用到底引用那个类的对象,也就无法知道调用那个类的虚函数。在程序运行时才知道具体指向那个类的对象, 然后通过虚表调用对应的虚函数,从而实现多态。
D:.正确,实现多态是要付出代价的,如虚表,虚表指针等,所以不实现多态就不要有虚函数了

5.关于重载、重写和重定义的区别说法【正确】的是(A、F )【多选哦】
A.重写和重定义都发生在继承体系中
B.重载既可以在一个类中,也可以在继承体系中
C.它们都要求原型相同
D.重写就是重定义
E.重定义就是重写
F.重写比重定义条件更严格
G.以上说法全错误

5:解析:
A:重写即覆盖,针对多态, 重定义即隐藏, 两者都发生在继承体系中。
B:重载只能在一个范围内,不能在不同的类里。
C:只有重写要求原型相同。
D/E:重写和重定义是两码事,重写即覆盖,针对多态, 重定义即隐藏。
F:重写要求函数完全相同,重定义只需函数名相同即可。

6.关于重载和多态【正确】的是(B )
A.如果父类和子类都有相同的方法,参数个数不同, 将子类对象赋给父类对象后, 采用
父类对象调用该同名方法时,实际调用的是子类的方法
B.选项全部都不正确
C.重载和多态在C++面向对象编程中经常用到的方法,都只在实现子类的方法时才会
使用
D.class A
 {
  public:
   void test(float a)
   { cout << a; }
 };
  class B :public A
  {
  public:
    void test(int b)
    { cout << b; }
 };
 void main()
 {
  A *a = new A;
  B *b = new B;
  a = b; a->test(1.1);
 }
结果是1

6:解析:
A:使用父类的对象调用函数,永远是父类的函数(方法)
C:重载是不涉及子类的,只需要在同一作用于就可以了。
D:a是父类的对象,调用函数还是父类的函数(方法)。

7.以下哪项说法时【正确】的(D )

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;}
};
A.基类和子类的f1函数构成重写
B.基类和子类的f3函数没有构成重写,因为子类f3前没有增加virtual关键字
C.基类引用引用子类对象后,通过基类对象调用f2时,调用的是子类的f2
D.f2和f3都是重写,f1是重定义

7:解析:
A:错误,构成重写是子类重写父类的虚函数。
B:构成重写,因为派生类在重写基类虚函数的时候,可以省略关键字virtual
C:题目前半句说的是基类引用 引用了子类对象,但是后半句调用虚函数时,说的是基类的对象调用f2,通过对象调用时编译期间就直接确定调用那个函数了,不会通过虚表以多态方式调用。基类对象调用函数,依然是基类里面对应的函数

==8.关于抽象类和纯虚函数的描述中,【错误】的是 (D )
A.纯虚函数的声明以“=0;”结束
B.有纯虚函数的类叫抽象类,它不能用来定义对象
C.抽象类的派生类如果不实现纯虚函数,它也是抽象类
D.纯虚函数不能有函数体

8:解析:
A.纯虚函数的声明以“=0;”结束,这是语法要求。
B.有纯虚函数的类叫抽象类,它不能用来定义对象,一般用于接口的定义。
C.子类不实现父类所有的纯虚函数,则子类还属于抽象类,仍然不能实例化对象。
D.纯虚函数可以有函数体,只是意义不大。

9.假设A为抽象类,下列声明【正确】的是(B)
A.A fun(int);
B.A*p;
C.int fun(A);
D.A obj;

9:解析:
A.抽象类不能实例化对象,所以以对象返回是错误
B.抽象类可以定义指针,而且经常这样做,其目的就是用父类指针指向子类从而实现多态
C.参数为对象,所以错误
D.直接实例化对象,这是不允许的

10.关于虚表说法正确的是( D)
A.一个类只能有一张虚表
B.基类中有虚函数,如果子类中没有重写基类的虚函数,此时子类与基类共用同一张虚表
C.虚表是在运行期间动态生成的
D.一个类的不同对象共享该类的虚表

10:解析:
A.多继承的时候,就会可能有多张虚表。
B.父类对象的虚表与子类对象的虚表没有任何关系,这是两个不同的对象。
C.虚表是在编译期间生成的。
D.一个类不同对象共享该类的虚表。

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

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();
 return 0;
}
A.B::f()
B.A::f(),因为子类的f()函数是私有的
C.A::f(),因为强制类型转化后,生成一个基类的临时对象,pa实际指向的是一个基类的临时对象
D.编译错误,私有的成员函数不能在类外调用

11:解析:
首先从主函数中可以看到是基类的指针调用的函数。并且该函数是构成多态的,因此指向谁调用谁,所以是B::f()
A.正确
B.虽然子类函数为私有,但是多态仅仅是用子类函数的地址覆盖虚表,最终调用的位置不变,只是执行函数发生变化
C.不强制也可以直接赋值,因为赋值兼容规则作出了保证
D.编译是正确的

12.如果类B继承类A,A::x()被声明为虚函数,B::x()重写了A::x()方法,下述语句中 哪个x()方法会被调用:( B)
B b; b.x();
A.A::x()
B.B::x()
C.A::x() B::x()
D.B::x() A::x()

12:解析:
虽然子类重写了父类的虚函数,但只要是用对象去调用,则只能调用相对类型的方法。也就是说不符合多态的用基类指针或引用调用函数

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

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;
}
A.1 0
B.0 1
C.0 1 2
D.2 1 0
E.不可预期
F. 以上都不对

13:解析:
new B时先调用父类A的构造函数,执行test()函数,在调用func()函数,由于此时还处于对象构造阶段,多态机制还没有生效,所以,此时执行的func函数为父类的func函数,打印0,构造完父类后执行子类构造函数,又调用test函数,然后又执行func(),由于父类已经构造完毕,虚表已经生成,func满足多态的条件,所以调用子类的func函数,对成员m_iVal加1,进行打印,所以打印1, 最终通过父类指针p->test(),也是执行子类的func,所以会增加m_iVal的值,最终打印2, 所以答案为C: 0 1 2

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

14:解析;
A.父类对象和子类对象的前4字节都是虚表地址
B.A类对象和B类对象前4个字节存储的都是虚表的地址,只是各自指向各自的虚表
C.不相同,各自有各自的虚表
D.A类和B类不是同一类内容不同

15.假设D类先继承B1,然后继承B2,B1和B2基类均包含虚函数,D类对B1和B2基类的虚函数重写了,并且D类增加了新的虚函数,则:(B )
A.D类对象模型中包含了3个虚表指针
B.D类对象有两个虚表,D类新增加的虚函数放在第一张虚表最后
C.D类对象有两个虚表,D类新增加的虚函数放在第二张虚表最后
D.以上全部错误

15:解析:
A.D类有几个父类,如果父类有虚函数,则就会有几张虚表,自身子类不会产生多余的虚表,所以只有2张虚表
B.正确
C.子类自己的虚函数只会放到第一个父类的虚表后面,其他父类的虚表不需要存储,因为存储了也不能调用
D.错误

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

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

相关文章

< 基础物理 >

SI国际单位制 常见的公制单位 为什么需要单位&#xff0c;是统一衡量的标准 通过国际单位&#xff0c;以及单位的拓展&#xff0c;以及单位的组合&#xff0c;形成一系列新的测量单位 面积 m^2 速率 m/s 米每二次方秒&#xff0c;m / s, delta表示增量, 每秒移动多少米 加…

手写体识别毕设——人工智能和深度学习技术的快速发展

引言 研究背景 随着人工智能和深度学习技术的快速发展,手写体识别作为其中的一项重要应用,受到了广泛关注。手写体识别技术可以应用于教育、金融、医疗等多个领域,对于提高识别效率和准确性具有重要意义。

C++深入学习string类成员函数(3):访问与修饰

引言 在 C 中&#xff0c;std::string 提供了丰富的成员函数来访问和修改字符串中的字符。通过这些函数&#xff0c;程序员可以灵活地处理字符串中的各个元素&#xff0c;无论是读取特定位置的字符&#xff0c;还是修改字符串的内容。此外&#xff0c;std::string 类还确保了访…

git使用“保姆级”教程3——添加暂存区及提交本地库

1、存入暂存区——命令行git add 要将代码放入暂存区&#xff0c;要使用git add指令注意&#xff1a;只是把在工作区的文件往暂存区复制了一份&#xff0c;并不是工作区的文件就消失了 将单文件放在暂存区 // 把文件夹下的1.txt文本放在暂存区 > 1.txt可以替换成任意文件名…

搭建高效知识库:教培机构数字教学的关键一步

在数字化时代&#xff0c;教育培训行业正经历着前所未有的变革。随着在线教育的兴起和个性化学习需求的增长&#xff0c;构建一个高效、易用的知识库已成为教培机构提升教学质量、优化学习体验、增强竞争力的关键一步。本文将深入探讨构建高效知识库的重要性&#xff0c;以及如…

简站wordpress主题产品多图ACF插件设置方法

此教程仅适用于演示站有产品多图的主题&#xff0c;演示站没有产品多图的主题&#xff0c;就别往下看了&#xff0c;省得浪费时间。 1、给产品添加轮播图 简站wordpress主题有多个产品图的主题&#xff0c;添加产品轮播图的具体方法如下&#xff1a; 1.2、选择产品分类 添加…

【管理】销售管理到底应该怎么管?

销售是个数字游戏&#xff0c;销售管理的最终目的就是完成销售业绩。有人说销售管理是门艺术&#xff0c;有人说销售管理是科学。销售是一门艺术&#xff0c;但是可以通过科学的方式将这些艺术固化很多人对销售管理的认识存在很多不同&#xff0c;我们尝试用最为平时的语言总结…

黑马程序员pink前端查漏补缺笔记,耗时6天,针对必要案例进行练习

HTML 1&#xff09;插件 自动闭合标签&#xff0c;修改开标签时闭标签跟着变&#xff08;微信开发者工具没有这个功能&#xff09; 主题 保存格式化 浏览器打开 实时刷新&#xff0c;不用按浏览器的刷新按钮 win←/→ 快速分屏 2&#xff09;初始结构标签 文档类型声明标签…

在已安装的openresty上添加安装upstream模块报错的解决以及使用Consul服务发现时定时变更nginx的upstream的shell脚本

一、在已经安装好的openresty环境上添加安装upstream模块报错&#xff1a; 在已经安装好的openresty环境上添加安装upstream模块报错&#xff1a;http upstream check module can not find any check server, make sure you ve added the check 的问题解决。 服务器上已经安装好…

Unity3D入门(四) : Android和Unity3D交互 - Unity调用Android

1. 前言 上篇文章&#xff0c;我们讲了如何通过Android调用Unity3D。这篇文章&#xff0c;我们来讲一下Unity3D怎么调用Android。 1.1 unity和Android的三种通信方式 Unity官方提供的接口 : 有一个弊端&#xff0c;它有一个传输内容量的一个限制&#xff0c;传输内容过大或过…

详解JavaScript中的数组

第7章 数组 JavaScript数组索引基于32位数值&#xff0c;以0开头&#xff0c;最大索引2^32-2&#xff0c;最大容纳4294967295&#xff0c;大约42亿个。 JavaScript数组是动态的&#xff0c;根据需要增长或缩减&#xff0c;可能是稀疏的&#xff0c;有length属性。 用数字索引…

Linux下的驱动开发一

设备驱动 设备驱动程序&#xff08;Device Driver&#xff09;是操作系统中的一种软件组件&#xff0c;负责管理和控制计算机硬件设备的工作。驱动程序通过提供操作系统和硬件设备之间的接口&#xff0c;使得操作系统和应用程序能够与硬件设备进行交互&#xff0c;而无需了解硬…

【智能大数据分析 | 实验二】Spark实验:部署Spark集群

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘&#xff0c;以提取有价值的信息和洞察。它结合了大数据技术、人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&a…

网易云多久更新一次ip属地

‌在数字化时代&#xff0c;网络成为了我们日常生活中不可或缺的一部分。无论是社交娱乐还是工作学习&#xff0c;IP地址作为网络身份的象征&#xff0c;都扮演着重要的角色。对于网易云音乐这样的热门应用来说&#xff0c;IP属地的显示不仅关乎用户体验&#xff0c;也涉及用户…

Supervisor进程管理工具安装

Supervisor进程管理工具安装 一、Supervisor概况及作用1.概况2.主要作用1&#xff09;、进程管理(1). 启动与停止进程(2). 自动重启进程(3). 进程状态监控 2&#xff09;、日志管理(1).集中化日志记录 3&#xff09;、资源管理与优化(1). 控制进程资源使用 二.安装 Supervisor1…

小白学大模型RAG:十大步骤分析GraphRAG的工作原理

对于普通的RAG&#xff0c;也就是前面课程讲的RAG&#xff0c;它的原理是通过将文本进行切分和向量化&#xff0c;通过计算文本之间的向量相似度&#xff0c;从而得到两个文本之间的语义相似度&#xff0c;从知识库中找出跟问题语义相似的知识点&#xff0c;再送给LLM得出最终答…

学习Java (五)

1.学习封装 package com.msb.test07; //封装 public class Girl {private int age; // 赋值public void setAge(int age){if(age > 30){this.age 18;}else{this.age age;}} // 读取public int getAge(){return age;} }package com.msb.test07;public class Test {p…

【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法

一、报错原因 我们使用 make 命令&#xff0c;想要将 text.c 文件编译形成 可执行文件 text 时&#xff0c;报错如下 make: test is up to date. 中文含义&#xff1a;test 文件已经达到最新状态 意思是&#xff1a; test.c 文件里面的 所有源代码都没有修改过&#xff0c;你…

c++11~c++20 numeric_limits

在c中应该尽量少使用宏&#xff0c;用模板取而代之是明知的选择。我们可以使用numeric_limits来获取最大值和最小值&#xff0c;例如 #include <iostream> #include <limits> #include <iostream> using namespace std;int main() {cout << "int…

Go基础学习04-变量重声明;类型转换;类型断言;Unicode代码点;类型别名;潜在类型

目录 变量重声明 类型断言 类型转换 类型转换注意事项 Unicode代码点 类型别名、潜在类型 类型别名的意义 变量重声明 编写代码&#xff1a; package mainimport "fmt"var container []string{"Beijing", "Shanghai"}func main() {fmt.Pr…