继承多态经典笔试题
注: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拦截器 (可能超出…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...