当前位置: 首页 > news >正文

继承多态经典笔试题

注:visual studio复制当前行粘贴到下一行: CTRL+D

杂项

调用子类重写的虚函数(带默认参数),但参数用的是基类的虚函数中的默认参数:

这是由于参数是在编译时压入

试题一

交换两个基类指针指向的对象的vfptr造成的运行结果变化

class Animal
{
public:Animal(string name) :_name(name) {}// 纯虚函数virtual void bark() = 0;
protected:string _name;
};
// 以下是动物实体类
class Cat : public Animal
{
public:Cat(string name) :Animal(name) {}void bark() { cout << _name << " bark: miao miao!" << endl; }
};
class Dog : public Animal
{
public:Dog(string name) :Animal(name) {}void bark() { cout << _name << " bark: wang wang!" << endl; }
};int main()
{Animal* p1 = new Cat("加菲猫");Animal* p2 = new Dog("二哈");int* p11 = (int*)p1;int* p22 = (int*)p2;int temp = p11[0]; // p11[0]访问Cat的前4个字节,即 指向Cat的vftable的vfptrp11[0] = p22[0];  // p22[0]访问Dog的前4个字节,即 指向Dog的vftable的vfptrp22[0] = temp;// 上面代码相当于交换了虚函数表指针// 导致下面调用虚函数时就发生了非预期的情况p1->bark(); // 实际调用Dog::bark()p2->bark(); // 实际调用Cat::bark()delete p1;delete p2;return 0;
}

试题二

有如下代码

#include <iostream>
#include <string>
using namespace std;class Base
{
public:virtual void show(int i = 10){cout << "call Base::show i:" << i << endl;}
};
class Derive : public Base
{
public:void show(int i = 20){cout << "call Derive::show i:" << i << endl;}
};
int main()
{Base* p = new Derive();p->show();delete p;return 0;
}
// 输出结果
// call Derive::show i:10

发现调用的是派生类覆盖的函数,确实是动态绑定,但使用的参数却是基类虚函数的默认参数,而不是派生类重写的虚函数的默认值。

原因是函数调用参数压栈是在编译时期,具体call函数可以在运行时,p->show() 汇编指令大致如下:

push 0Ah # 压入基类的默认实参10
mov eax, dword ptr[p]
mov ecx, dword ptr[eax]
call ecx

试题三

利用多态能调用到派生类private成员函数

#include <iostream>
#include <string>
using namespace std;class Base
{
public:virtual void show(int i = 10){cout << "call Base::show " << endl;}
};
class Derive : public Base
{
private:void show(int i = 20){cout << "call Derive::show" << endl;}
};
int main()
{Base* p = new Derive();// 成员方法限定符是在【编译时】检查,由于编译时通过p检查的是Base::show(),没有问题// 而运行时调用子类覆盖的成员这不影响函数执行p->show(); // 最终调用到Derive::show(),是在运行时期确定delete p;return 0;
}// 输出结果:call Derive::show

如果把基类的虚函数访问权限设置为private,则在编译阶段无法通过

试题四

说明下面代码段一和二是否正确执行,说明理由

#include <iostream>
#include <string>
using namespace std;class Base
{
public:Base(){cout << "call Base()" << endl;clear();}// !!!!!!!!!!!!!!!!!!!!!!!!void clear() { memset(this, 0, sizeof(*this)); }virtual void show(){cout << "call Base::show()" << endl;}
};
class Derive : public Base
{
public:Derive(){cout << "call Derive()" << endl;}void show(){cout << "call Derive::show()" << endl;}
};
int main()
{// 代码段一Base* pb1 = new Base();pb1->show();delete pb1;// 代码段二/*Base* pb2 = new Derive();pb2->show();delete pb2;*/return 0;
}

解答:

代码段一执行失败

因为new Base()调用构造函数时,进入第一行代码前会生成vfptr(就是将vftable地址写入其中),指向Base类对应的虚函数表,但是在构造函数中后面又调用clear函数将内存清0,导致vfptr被置零,随后调用 pb1->show(); 时会使用vfptr则会造成非法访问,运行时提示:

引发了异常: 读取访问权限冲突。

pb1->**** 是 nullptr

代码段二执行成功

执行 new Derive(); 时先调用基类构造,虽然在构造函数中也会使vfptr被清零,但是随后调用派生类构造会将子类的vftable地址赋值给vfptr,所以导致最后通过 pb2->show(); 访问vfptr是没问题的

相关文章:

继承多态经典笔试题

注&#xff1a;visual studio复制当前行粘贴到下一行&#xff1a; CTRLD 杂项 调用子类重写的虚函数&#xff08;带默认参数&#xff09;&#xff0c;但参数用的是基类的虚函数中的默认参数&#xff1a; 这是由于参数是在编译时压入 试题一 交换两个基类指针指向的对象的vf…...

如何使用Typeface-Helper-自定义字体

随着科技的不断发展&#xff0c;人们对于视觉效果的要求也越来越高。在设计领域中&#xff0c;字体设计是非常重要的一环&#xff0c;因为它直接影响了整个设计的风格和品质。因此&#xff0c;越来越多的设计师开始寻找能够帮助他们自定义字体的工具。在这个过程中&#xff0c;…...

SubMain CodeIt.Right 2022.2 Crack

CodeIt.Right&#xff0c;从源头上提高产品质量&#xff0c;在编写代码时获取有关问题的实时反馈&#xff0c;支持最佳实践和合规性&#xff0c;自动执行代码审查&#xff0c;轻松避免与您的群组无关的通知&#xff0c;一目了然地了解代码库的运行状况 自动执行代码审查 使用自…...

文艺复兴的核心是“以人为本”:圣母百花大教堂(Duomo)

文章目录 引言I 圣母百花大教堂的建筑技术故事1.1 布鲁内莱斯基1.2 表现三维立体的透视画法II 美第奇家族的贡献2.1 科西莫德美第奇2.2 洛伦佐美第奇III 历史中的偶然性与必然性。3.1 文艺复兴的诞生其实是必然的事情3.2 文艺复兴的偶然性引言 从科技的视角再次理解文艺复兴,…...

校招失败后,在小公司熬了 2 年终于进了百度,竭尽全力....

其实两年前校招的时候就往百度投了一次简历&#xff0c;结果很明显凉了&#xff0c;随后这个理想就被暂时放下了&#xff0c;但是这个种子一直埋在心里这两年除了工作以外&#xff0c;也会坚持写博客&#xff0c;也因此结识了很多优秀的小伙伴&#xff0c;从他们身上学到了特别…...

【C++学习】函数模板

模板的概念 模板就是建立通用的模具&#xff0c;大大提高复用性。 模板的特点&#xff1a; 模板不可以直接使用&#xff0c;它只是一个模型 模板的通用不是万能的 基本语法 C中提供两种模板机制&#xff1a;函数模板和类模板 函数模板作用&#xff1a; 建立一个通用函数&…...

1960-2014年各国二氧化碳排放量(人均公吨数)

1960&#xff0d;2014年各国二氧化碳排放量&#xff08;人均公吨数&#xff09;&#xff08;世界发展指标, 2019年12月更新&#xff09; 1、来源&#xff1a;世界发展指标 2、时间&#xff1a;1960&#xff0d;2014年 3、范围&#xff1a;世界各国 4、指标&#xff1a; 二氧…...

【java-04】深入浅出多态、内部类、常用API

主要内容 多态 内部类 常用API 1 多态 1.1 面向对象三大特征 ? 封装 , 继承 , 多态 1.2 什么是多态 ? 一个对象在不同时刻体现出来的不同形态 举例 : 一只猫对象 我们可以说猫就是猫 : Cat cat new Cat();我们也可以说猫是动物 : Animal cat new Cat();这里对象在不…...

【逐函数详细讲解ORB_SLAM2算法和C++代码|Viewer|1-26】

Viewer类的主要目的是实现ORB-SLAM2算法的可视化部分,帮助用户更好地理解算法的运行过程和结果。为此,Viewer类与其他类(如System、FrameDrawer、MapDrawer和Tracking)协同工作,根据摄像机的帧率实时更新可视化界面。 在Viewer类中,有一些成员变量和成员函数。 成员变量…...

【C语言】测试2 C程序设计初步

以下能正确定义整型变量 a,b 和 c,并对它们赋初值为5的语句是( )。 A. int a=b=c=5; B. int a, b, c=5; C. int a=5, b=5, c=5; D. a=b=c=5; 正确答案: C 当输入数据的形式为:25,13,10<回车 >时,以下程序的输出结果为( )。 main() {int x,y,z; scanf(“ %…...

SpringBoot3 integrate SpringDoc

SpringDoc 官方文档 Springdoc3取代swagger2 pom xml加载Springdoc JarOpenAPIDefinition&#xff0c;声明一个OpenAPI对API进行分组&#xff0c;方便查询访问地址springdoc ConfigurationRequestMapping pom xml加载Springdoc Jar <dependency><groupId>org.sprin…...

一文解决Xshell无法连接vmware上的centos

问题描述 win10系统上安装VMware workstation16 pro&#xff0c;装好后安装centos虚拟机&#xff0c;在设置network & hostname时选择的NAT模式&#xff0c;即使用自定义的网关和IPv4地址&#xff0c;最后配置完成后centos主机地址信息如下&#xff0c;在虚拟机内部进行pi…...

ATTCK v13版本战术介绍——防御规避(五)

一、引言 在前几期文章中我们介绍了ATT&CK中侦察、资源开发、初始访问、执行、持久化、提权战术理论知识及实战研究、部分防御规避战术&#xff0c;本期我们为大家介绍ATT&CK 14项战术中防御规避战术第25-30种子技术&#xff0c;后续会介绍防御规避其他子技术&#xf…...

祁宁:社区问答是激荡企业高级智慧的头脑风暴 | 开发者说

在祁宁家里&#xff0c;有一套完整的赛车模拟器&#xff0c;他甚至还请人到国外代购了最新的 VR 设备。作为沉浸式赛车游戏发烧友&#xff0c;除了享受速度与激情带来的愉悦感&#xff0c;祁宁在玩的过程中更多的是思考如何将技术能力进行产品化的问题。 Answer.dev 就是将技术…...

linux安装

1. 准备前说明 本文采用的是CentOS6.8&#xff0c;64位的&#xff0c;虚拟机时VMvare&#xff0c;采用的是双网卡方式。至于双网卡的作用和nat&#xff0c;桥接和hostonly模式请参见我的另一篇文章。安装回环网卡&安装Linux前准备 2. 废话不多说&#xff0c;开始了 ◆打…...

【Go编程语言】 Go语言基础语法

Go语言基础语法 文章目录 Go语言基础语法一、注释1.单行注释2.多行注释 二、变量1.变量的定义2.变量的初始化3.理解变量&#xff08;内存地址&#xff09;4.变量交换5.匿名变量6.变量的作用域 三、常量1.常量的定义&#xff1a; const2.iota&#xff08;特殊常量&#xff09; 四…...

洗稿用什么软件-洗稿软件免费

洗稿文章的主要优势 洗稿文章的主要优势在于提高文章的质量和效率。以下是洗稿文章的几个主要优势&#xff1a; 优化结构和语言 洗稿可以删除冗余、无用和重复的内容&#xff0c;同时对文章的结构和语言进行优化&#xff0c;提高文章的可读性和吸引力。这可以使文章更加专业…...

网络请求发送

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版&#xff0c;配图更多&#xff0c;CSDN博文图片需要手动上传&#xff0c;因此文章配图较少&#xff0c;看不懂的可以去菜鸡博客参考一下配图&#xff01; 系列文章目录 前端系列文章——传送门 后端系列文章——传送…...

微信小程序开发

文章目录 1 开发准备工作2 小程序开发工具使用3 初始化项目4 index页静态搭建5 数据绑定5.1 初始化数据5.2 使用数据5.3 修改数据 6 数据绑定---小程序&#xff0c;Vue&#xff0c;React7 事件绑定7.1 事件分类7.2 绑定事件7.3 向事件对象传参7.4 补充&#xff1a;事件流的三个…...

number类型超出16位的问题(前端、后端处理)

目录 1、前端解决方案 1.1 甩链接 1.2 接口返回数据过程中将数据处理为字符串&#xff08;过过嘴瘾&#xff09; 1.3 对返回的json字符串进行数据预处理代码如下 2、后端解决方案 2.1 toString、String、 、new String() 自己悟、就是要改的地方多。 2.2拦截器 (可能超出…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...