继承多态经典笔试题
注: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是没问题的
相关文章:
继承多态经典笔试题
注:visual studio复制当前行粘贴到下一行: CTRLD 杂项 调用子类重写的虚函数(带默认参数),但参数用的是基类的虚函数中的默认参数: 这是由于参数是在编译时压入 试题一 交换两个基类指针指向的对象的vf…...
如何使用Typeface-Helper-自定义字体
随着科技的不断发展,人们对于视觉效果的要求也越来越高。在设计领域中,字体设计是非常重要的一环,因为它直接影响了整个设计的风格和品质。因此,越来越多的设计师开始寻找能够帮助他们自定义字体的工具。在这个过程中,…...
SubMain CodeIt.Right 2022.2 Crack
CodeIt.Right,从源头上提高产品质量,在编写代码时获取有关问题的实时反馈,支持最佳实践和合规性,自动执行代码审查,轻松避免与您的群组无关的通知,一目了然地了解代码库的运行状况 自动执行代码审查 使用自…...
文艺复兴的核心是“以人为本”:圣母百花大教堂(Duomo)
文章目录 引言I 圣母百花大教堂的建筑技术故事1.1 布鲁内莱斯基1.2 表现三维立体的透视画法II 美第奇家族的贡献2.1 科西莫德美第奇2.2 洛伦佐美第奇III 历史中的偶然性与必然性。3.1 文艺复兴的诞生其实是必然的事情3.2 文艺复兴的偶然性引言 从科技的视角再次理解文艺复兴,…...
校招失败后,在小公司熬了 2 年终于进了百度,竭尽全力....
其实两年前校招的时候就往百度投了一次简历,结果很明显凉了,随后这个理想就被暂时放下了,但是这个种子一直埋在心里这两年除了工作以外,也会坚持写博客,也因此结识了很多优秀的小伙伴,从他们身上学到了特别…...
【C++学习】函数模板
模板的概念 模板就是建立通用的模具,大大提高复用性。 模板的特点: 模板不可以直接使用,它只是一个模型 模板的通用不是万能的 基本语法 C中提供两种模板机制:函数模板和类模板 函数模板作用: 建立一个通用函数&…...
1960-2014年各国二氧化碳排放量(人均公吨数)
1960-2014年各国二氧化碳排放量(人均公吨数)(世界发展指标, 2019年12月更新) 1、来源:世界发展指标 2、时间:1960-2014年 3、范围:世界各国 4、指标: 二氧…...
【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,声明一个OpenAPI对API进行分组,方便查询访问地址springdoc ConfigurationRequestMapping pom xml加载Springdoc Jar <dependency><groupId>org.sprin…...
一文解决Xshell无法连接vmware上的centos
问题描述 win10系统上安装VMware workstation16 pro,装好后安装centos虚拟机,在设置network & hostname时选择的NAT模式,即使用自定义的网关和IPv4地址,最后配置完成后centos主机地址信息如下,在虚拟机内部进行pi…...
ATTCK v13版本战术介绍——防御规避(五)
一、引言 在前几期文章中我们介绍了ATT&CK中侦察、资源开发、初始访问、执行、持久化、提权战术理论知识及实战研究、部分防御规避战术,本期我们为大家介绍ATT&CK 14项战术中防御规避战术第25-30种子技术,后续会介绍防御规避其他子技术…...
祁宁:社区问答是激荡企业高级智慧的头脑风暴 | 开发者说
在祁宁家里,有一套完整的赛车模拟器,他甚至还请人到国外代购了最新的 VR 设备。作为沉浸式赛车游戏发烧友,除了享受速度与激情带来的愉悦感,祁宁在玩的过程中更多的是思考如何将技术能力进行产品化的问题。 Answer.dev 就是将技术…...
linux安装
1. 准备前说明 本文采用的是CentOS6.8,64位的,虚拟机时VMvare,采用的是双网卡方式。至于双网卡的作用和nat,桥接和hostonly模式请参见我的另一篇文章。安装回环网卡&安装Linux前准备 2. 废话不多说,开始了 ◆打…...
【Go编程语言】 Go语言基础语法
Go语言基础语法 文章目录 Go语言基础语法一、注释1.单行注释2.多行注释 二、变量1.变量的定义2.变量的初始化3.理解变量(内存地址)4.变量交换5.匿名变量6.变量的作用域 三、常量1.常量的定义: const2.iota(特殊常量) 四…...
洗稿用什么软件-洗稿软件免费
洗稿文章的主要优势 洗稿文章的主要优势在于提高文章的质量和效率。以下是洗稿文章的几个主要优势: 优化结构和语言 洗稿可以删除冗余、无用和重复的内容,同时对文章的结构和语言进行优化,提高文章的可读性和吸引力。这可以使文章更加专业…...
网络请求发送
私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版,配图更多,CSDN博文图片需要手动上传,因此文章配图较少,看不懂的可以去菜鸡博客参考一下配图! 系列文章目录 前端系列文章——传送门 后端系列文章——传送…...
微信小程序开发
文章目录 1 开发准备工作2 小程序开发工具使用3 初始化项目4 index页静态搭建5 数据绑定5.1 初始化数据5.2 使用数据5.3 修改数据 6 数据绑定---小程序,Vue,React7 事件绑定7.1 事件分类7.2 绑定事件7.3 向事件对象传参7.4 补充:事件流的三个…...
number类型超出16位的问题(前端、后端处理)
目录 1、前端解决方案 1.1 甩链接 1.2 接口返回数据过程中将数据处理为字符串(过过嘴瘾) 1.3 对返回的json字符串进行数据预处理代码如下 2、后端解决方案 2.1 toString、String、 、new String() 自己悟、就是要改的地方多。 2.2拦截器 (可能超出…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...
tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
SQL进阶之旅 Day 22:批处理与游标优化
【SQL进阶之旅 Day 22】批处理与游标优化 文章简述(300字左右) 在数据库开发中,面对大量数据的处理任务时,单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”,深入探讨如何通过批量操作和游标技术提…...
