C++反汇编——多态,面试题01

文章目录

  • 1.C++的三大特性
    • 1.1封装
    • 1.2继承
    • 1.3多态
      • 1.3.1 虚函数
      • 1.3.2 多态代码+反汇编分析。
        • 反汇编分析1——基类指针指向子类对象,构造过程。
        • 反汇编分析2——基类指针指向子类对象,调用虚函数getPrice()过程。
        • 反汇编分析3——基类对象,调用虚函数getPrice()过程。
        • 反汇编分析4——基类指针指向子类对象,析构过程。
        • 反汇编分析5——基类指针指向子类对象,析构过程,基类析构函数不是虚函数时。
      • 1.3.3 静态多态vs动态多态

1.C++的三大特性

1.1封装

将对象的属性和方法封装起来。为了模块化,便于使用者操作,同时可以隔离外部使用者对内部数据的干扰,提高了安全性。

类成员的三种属性:
private:本类使用。设置get和set方法,因为通过接口来访问和修改数据是可控的,相对安全。
protected:本类和子类使用。
public:公开的,都可以访问。

1.2继承

允许通过继承原有类的某些特性或全部特性而产生新的类,原有的类称为基类(父类),产生的类称为派生类(子类)。为了扩展和重用,减少重复代码。

1.3多态

发生在继承关系中,不同的对象,对于相同的方法有不同的操作逻辑。为了接口重用,提高代码的可复用性、可维护性和可扩充性。

多态的实现机制为虚函数。

1.3.1 虚函数

关键字:virtual

作用:允许在子类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和子类的同名函数。

最常见的用法:声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。

实现原理:虚表+虚表指针。
在这里插入图片描述
当类存在虚函数时,编译器会为类创建一个虚表,虚表是一个数组,数组的元素存放的是虚函数地址。同时为每个类对象添加一个隐藏数据成员,即虚表指针,它被定义在对象首地址处。
【注意】 虚表只有一份,而有多少个对象,就有多少个虚表指针。

1.3.2 多态代码+反汇编分析。

1.定义了一个基类,图形类Shape,数据成员分别为价格price和面积area,两个虚成员函数分别为获取图形描述getDescription()和获取图形价格getPrice(),虚析构函数;
2.定义了一个子类,圆形类Circle,继承Shape,数据成员为半径radius,重写父类方法getDescription()和getPrice();
3.定义了一个子类,矩形类Rectangle,继承Shape,数据成员分别为长度length和宽度width,重写父类方法getDescription()和getPrice();
4.main()里,基类指针s1指向Circle类对象,基类指针s2指向Rectangle类对象,基类对象s3。

// ConsoleApplication5.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include<iostream>
#include<string>
using namespace std;

class Shape 
{
protected:
    double price;
    double area;

public:
    Shape() :price(100),area(0) {}
    virtual ~Shape() { printf("%s\n", "Delete shape"); }

    virtual void getDescription() { printf("%s\n", "Base shape");}
    virtual void getPrice() { printf("%s%f\n", "Shape price ",price); }
};

class Circle : public Shape 
{
private:
    double radius; 

public:
    Circle(double r) : radius(r) { area = 3.14 * radius * radius; price = 100 + area * 6; }
    ~Circle() { printf("%s%f\n", "Delete circle with radius ",radius); }

    void getDescription() { printf("%s%f\n", "Circle with radius ",radius);}
    void getPrice(){ printf("%s%f%s%f\n", "Circle with area ", area," price ",price); }
};

class Rectangle : public Shape {
private:
    double length;
    double width;  

public:
    Rectangle(double l, double w) : length(l), width(w) { area = length * width; price = 100 + area * 6; }
    ~Rectangle() { printf("%s%f%s%f\n", "Delete rectangle with length ", length," and width ",width); }

    void getDescription() { printf("%s%f%s%f\n","Rectangle with length ", length, " and width ", width);}
    void getPrice() { printf("%s%f%s%f\n", "Rectangle with area ", area, " price ", price); }
};

int main() {
   
    Shape* s1 = new Circle(5.0);
    Shape* s2 = new Rectangle(4.0, 6.0);
    s1->getPrice();
    s2->getPrice();

    Shape s3;
    s3.getPrice();
    s3.getDescription();

    delete s1;
    delete s2;

    _CrtDumpMemoryLeaks();
    return 0;
}

程序执行结果,如下图。
在这里插入图片描述

反汇编分析1——基类指针指向子类对象,构造过程。

1.调用子类构造函数(Rectangle),如下图。
在这里插入图片描述

2.调用父类构造函数(Shape),如下图。
看寄存器eax,对象s2地址0x014E5AB8;
虚表指针0x00DC9E10;
length地址eax+18h,0x0014E5AD0;
width地址eax+20h,0x0014E5AD8;
在这里插入图片描述
area=length * width,area地址eax+10h,0x0014E5AC8。
price=100 + area * 6,price地址eax+8h,0x0014E5AC0,如下图。
请添加图片描述
基类数据成员声明顺序price、area。
子类数据成员声明顺序length、width,如下图。
在这里插入图片描述

反汇编分析2——基类指针指向子类对象,调用虚函数getPrice()过程。

1.取对象s2地址,存放进eax,0x014E5AB8。
2.取虚表指针,存放进edx,0x00DC9E10。
3.取虚函数getPrice()地址,0x00DC14D3,并调用,如下图。
在这里插入图片描述

反汇编分析3——基类对象,调用虚函数getPrice()过程。

基类对象调用自身虚函数时,没有构成多态性,所以没必要查表访问,编译器使用了直接调用方式,如下图。

基类对象s3地址0x0118FE90。
虚表指针0x00DC9F64。
虚析构函数地址0x00DC14BF。
虚函数getDescription()地址0x00DC10CD。
虚函数getPrice()地址0x00DC14CE。

虚函数声明顺序:析构函数、getDescription()、getPrice()。
在这里插入图片描述

反汇编分析4——基类指针指向子类对象,析构过程。

在这里插入图片描述
在这里插入图片描述
1.调用子类析构函数(Circle),如下图。
在这里插入图片描述
2.释放子类资源后,调用父类析构函数(Shape),如下图。
在这里插入图片描述

反汇编分析5——基类指针指向子类对象,析构过程,基类析构函数不是虚函数时。

只调用基类析构函数,如下图。
【注意】 由于子类析构函数不会被调用,子类资源没有正确释放,造成内存泄漏。
在这里插入图片描述
在这里插入图片描述

1.3.3 静态多态vs动态多态

1.静态多态在编译期完成,由模板实现;而动态多态在运行期完成,由继承、虚函数实现。
2.静态多态中接口是隐式的,以有效表达式为中心;而动态多态中接口是显式的,以函数签名为中心。
3.【注意】 虚函数表在编译的时候就确定了,而类对象的虚函数指针是在运行阶段确定的,这是实现多态的关键!

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

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

相关文章

版本控制工具之Git的基础使用教程

Git Git是一个分布式版本控制系统&#xff0c;由Linux之父Linus Torvalds 开发。它既可以用来管理和追踪计算机文件的变化&#xff0c;也是开发者协作编写代码的工具。 本文将介绍 Git 的基础原理、用法、操作等内容。 一、基础概念 1.1 版本控制系统 版本控制系统&#x…

PSoc™62开发板之IoT应用

实验目的 使用PSoc62™开发板驱动OLED模块&#xff0c;实时监控室内的光照强度、温度信息 实验准备 PSoc62™开发板SSD1309 OLED模块DS18B20温度传感器BH1750光照传感器 模块电路 SSD1309 OLED模块的电路连接和模块配置教程请参考之前的文章&#xff0c;这里不详细展开描…

汽车EDI:IAC Elmdon EDI 对接指南

近期收到客户C公司的需求&#xff0c;需要与其合作伙伴IAC Elmdon建立EDI连接&#xff0c;本文将主要为大家介绍IAC Elmdon EDI 对接指南&#xff0c;了解EDI项目的对接流程。 项目需求 传输协议&#xff1a;OFTP2 IAC Elmdon 与其供应商之间使用的传输协议为OFTP2。OFTP2是…

云南区块链商户平台优化开发

背景 云南区块链商户平台是全省统一区块链服务平台。依托于云南省发改委、阿里云及蚂蚁区块链的国内首个省级区块链平台——云南省区块链平台同步上线&#xff0c;助力数字云南整体升级。 网页版并不适合妈妈那辈人使用&#xff0c;没有记忆功能&#xff0c;于是打算自己开发…

科技查新中医学科研项目查新点如何确立与提炼?案例讲解

一、前言 医学科技查新包括立项查新和成果查新两个部分&#xff0c;其中医学立项查新&#xff0c;它是指在医学科研项目申报开题之前&#xff0c;通过在一定范围内进行该课题的相关文献检索 ( 可以根据项目委托人的具体要求&#xff0c;进行国内检索或者进行国外检索 ) &#x…

媲美Suno、Udio!AI铁了心,要砸音乐人的饭碗

5月10日凌晨&#xff0c;著名语音生成式AI平台ElevenLabs在社交平台宣布&#xff0c;推出文本生成歌曲产品ElevenLabs Music。 从其展示的效果来看&#xff0c;音乐的节奏感、和声、乐器的搭配、情感表达、创意性、风格的多样性、高/低音&#xff0c;可媲美该领域的两款头部产…

k8s StatefulSet

Statefulset 一个 Statefulset 创建的每个pod都有一个从零开始的顺序索引&#xff0c;这个会体现在 pod 的名称和主机名上&#xff0c;同样还会体现在 pod 对应的固定存储上。这些 pod 的名称是可预知的&#xff0c;它是由 Statefulset 的名称加该实例的顺序索引值组成的。不同…

【元对象系统概述】

元对象系统概述 &#x1f31f; 元对象&#x1f31f; 元对象系统&#x1f31f; QT官方文档中给出的定义&#x1f31f;《Qt5.9 C开发指南》中给出的定义 &#x1f31f; 元对象 元对象是一个描述类的信息的数据结构&#xff0c;在qt中常常与QObject的类相关联。 可以通过QObject::…

这些企业注意!推荐使用OVSSL证书

JoySSL官网 注册码230918 SSL证书作为一种重要的安全措施&#xff0c;对于确保网站数据传输的安全性至关重要。而在众多SSL证书类型中&#xff0c;OV&#xff08;Organization Validation&#xff0c;组织验证&#xff09;SSL证书以其独特的功能和适用范围&#xff0c;成为众多…

夸克网盘免费扩容N次20T的方法

上文我们用&#xff1a;夸克网盘免费领取1TB空间的方法使自己的网盘扩容到1TB&#xff0c;但只有三个月还不够大。 所以用下面的方法那个免费的把自己的网盘扩容到20TB。 一、 登录任推邦 APP 需要借助这个平台&#xff0c;这是夸克网盘的第三方服务商&#xff0c;完善注册信…

2024年自动驾驶、车辆工程与智能交通国际会议(ICADVEIT2024)

2024年自动驾驶、车辆工程与智能交通国际会议&#xff08;ICADVEIT2024&#xff09; 会议简介 2024年自动驾驶、车辆工程和智能交通国际会议&#xff08;ICADVEIT 2024&#xff09;将在中国深圳举行。会议主要聚焦自动驾驶、车辆工程和智能交通等研究领域&#xff0c;旨在为从…

智慧便民小程序源码系统 求职招聘+房产出租+相亲交友 带完整的安装代码包以及系统搭建教程

在数字化、智能化的今天&#xff0c;我们的生活节奏越来越快&#xff0c;对于各种服务的需求也越发多元化和个性化。为了满足广大市民对于便捷、高效、全面的服务需求&#xff0c;罗峰给大家分享一款智慧便民小程序源码系统&#xff0c;集求职招聘、房产出租、相亲交友三大功能…

【全开源】Java U U跑腿同城跑腿小程序源码快递代取帮买帮送源码小程序+H 5+公众号跑腿系统

特色功能&#xff1a; 智能定位与路线规划&#xff1a;UU跑腿小程序能够利用定位技术&#xff0c;为用户提供附近的跑腿服务&#xff0c;并自动规划最佳路线&#xff0c;提高配送效率。订单管理&#xff1a;包括订单查询、订单状态更新、订单评价等功能&#xff0c;全行业覆盖…

Mac YOLO V9本地训练(命令行模式)

环境&#xff1a; Mac M1 (MacOS Sonoma 14.3.1) Python 3.11PyTorch 2.1.2 一、YOLO v9工程及模型准备 详见&#xff1a;Mac YOLO V9推理测试-CSDN博客 二、数据集准备 Roboflow Universe上有许多小规模的数据集&#xff0c;很适合用来进行目标检测。 首先安装依赖 pip …

NVIDIA 配置 Jetson 扩展针座

系列文章目录 前言 每个 Jetson 开发套件包括多个扩展接头和连接器&#xff08;统称 "接头"&#xff09;&#xff1a; 40 针扩展接头&#xff1a; 可让您将 Jetson 开发套件连接到现成的 Raspberry Pi HAT&#xff08;顶部附加硬件&#xff09;&#xff0c;如 Seee…

echarts-gl 离线3D地图

1、安装依赖 echarts-gl 与 echarts 版本关系&#xff1a; "echarts": "^5.2.0", "echarts-gl": "^2.0.8"# 执行安装 yarn add echarts-gl2、下载离线地图 免费下载实时更新的geoJson数据、行政区划边界数据、区划边界坐标集合_…

笨方法自学python(一)

我觉得python和c语言有很多相似之处&#xff0c;如果有c语言基础的话学习python也不是很难。这一系列主要是学习例题来学习python&#xff1b;我用的python版本是3.12 代码编辑器我用的是notepad&#xff0c;运行py程序用cmd 现在开始写第一个程序&#xff1a; print ("…

Photoshop中绘图及图像修饰工具的应用

Photoshop中绘图及图像修饰工具的应用 Photoshop中的颜色设置与取样前景色与背景色颜色取样 Photoshop中的颜色替换工具Photoshop中的渐变工具Photoshop中的描边命令Photoshop中的填充工具采用油漆桶进行填充采用填充命令进行填充 Photoshop中的擦除工具 Photoshop中的颜色设置…

图像是AI画的吗?OpenAI新神器帮你一键识破!|TodayAI

OpenAI宣布即将推出一款新的AI图像检测工具&#xff0c;此举意在帮助用户辨认图像是否由其开发的DALL-E图像生成器制作&#xff0c;并监控由该技术生成的内容。同时&#xff0c;该公司还计划为这些AI生成的图像加入新的水印&#xff0c;以便用户更容易识别这些作品是否出自DALL…

深度学习课程论文精读——ESRGAN

目录 1.研究概述 2.论文创新 2.1 改进生成器的网络框架 2.2 改进判别器 2.3 改进感知损失 2.4 网络插值 3.实验 3.1 评价指标 3.2 训练细节 3.3 对比实验 3.4 消融实验 3.5 网络插值 4.总结 5.阅读参考 文章标题&#xff1a;《ESRGAN: Enhanced Super-Resolution…
最新文章