《C++代码分析》第三回:类成员函数覆盖父类函数的调用(分析this指针的变化)

news2024/10/5 13:53:18

一、前言

在C++的学习中我们知道,子类是可以覆盖父类的方法,这里我们探讨一下子类方法调用父类方法时this指针时如何变化的。

二、示例代码

#include "windows.h"
#include "windef.h"
#include <iostream>
#include <tchar.h>
using namespace std;

class People {
protected:
	int gender;
	float stature;
	float weight;
public:
	void GetInfo() {
		printf("%d--%f--%f\n", this->gender, this->stature, this->weight);
	}
	void SetInfo(int gender, float stature, float weight) {
		this->gender = gender;
		this->stature = stature;
		this->weight = weight;
	}
};

class Teacher :People {
private:
	int pay;
	char schoolName[20];
public:
	void GetInfo() {
		printf("%d--%f--%f--%d--%s\n", this->gender, this->stature, this->weight, this->pay, this->schoolName);
	}
	void SetInfo(int gender, float stature, float weight,int pay,char* schoolName) {
		__super::SetInfo(gender, stature, weight);
		this->pay = pay;
		memcpy(this->schoolName, schoolName, sizeof(this->schoolName));
	}
};

int _tmain() {
	Teacher t1;
	char schoolName[] = "ShangHaiDaZhuan";
	t1.SetInfo(1, 120, 180, 102402, schoolName);
	t1.GetInfo();
	return 0;
}

在这里插入图片描述
显然父类的GetInfo被子类覆盖,这里我们将在后面的汇编中简单的查看。注意我们调用子类的SetInfo中调用了父类的SetInfo,我们看看是如何获取People的this指针的

三、详解

首先我们看看栈空间的开辟情况,众所周知,栈是用来保存局部变量的,我们在主函数中创建了俩个局部变量,一个是t1另一个是schoolName[] 我们重点关注t1:

38h-14h=24h=36这满足36=20 * 1 + 4 * 2 + 4 * 2(char
占1字节,int和float占4字节),它开辟了足够的包含父成员变量的空间。

在这里插入图片描述在这里插入图片描述

PS:movss在俩个xmm指令寄存器之间或者内存位置和xmm寄存器之间复制标量浮点数

在这里插入图片描述
this指针的第一层传递(指向Teacher类的),默认使用ecx进行传递

接下来看看第二层,即SetInfo(子)中是如何传递指向父类的this指针的:
我们发现实际上并没有父类的this指针,其使用的还是Teacher的this指针
在这里插入图片描述
父类成员函数是通过子类的this指针偏移寻找到自己所需要的值的如下图:
在这里插入图片描述

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

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

相关文章

自学大数据第六天~HDFS命令

HDFS常用命令 查看hadoop版本 version hadoop version注意,没有 ‘-’ [hadoopmaster ~]$ hadoop version Hadoop 3.3.4 Source code repository https://github.com/apache/hadoop.git -r a585a73c3e02ac62350c136643a5e7f6095a3dbb Compiled by stevel on 2022-07-29T12:3…

蓝桥杯嵌入式(G4系列):定时器输出可调PWM

前言&#xff1a; 蓝桥杯定时器输出PWM的考点在历届真题中的出现次数较多&#xff0c;而且之前关于STM32的学习&#xff0c;我对于使用STM32Cubemx配置PWM的方式确实不是很熟悉&#xff0c;这里简单记录一下自己的学习过程。 STM32Cubemx配置部分&#xff1a; 这里我们是改编真…

yocto编译烧录和脚本解析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、初始化构建目录二、imx-setup-release.sh脚本解析三、编译单独编译内核四、烧录总结前言 本篇文章主要讲解如何在下载好源码之后进行编译和yocto的脚本解析…

剑指 Offer II 027. 回文链表

题目链接 剑指 Offer II 027. 回文链表 easy 题目描述 给定一个链表的 头节点 head&#xff0c;请判断其是否为回文链表。 如果一个链表是回文&#xff0c;那么链表节点序列从前往后看和从后往前看是相同的。 示例 1&#xff1a; 输入: head [1,2,3,3,2,1] 输出: true 示例…

多目标遗传算法NSGA-II原理详解及算法实现

在接触学习多目标优化的问题上&#xff0c;经常会被提及到多目标遗传算法NSGA-II&#xff0c;网上也看到了很多人对该算法的总结&#xff0c;但真正讲解明白的以及配套用算法实现的文章很少&#xff0c;这里也对该算法进行一次详解与总结。会有侧重点的阐述&#xff0c;不会针对…

理解并解决【跨域】问题--通过代理或【CROS】

文章目录一.理解跨域问题引起跨域问题的原因浏览器的同源策略二.跨域问题的解决办法解决方法1-------代理&#xff08;前端配置&#xff09;解决方法2-----开启跨域资源共享CORS&#xff08;后端&#xff09;知识小贴士一.理解跨域问题 主要出现在前后端分离项目 引起跨域问题…

磨金石教育摄影技能干货分享|春之旅拍

春天来一次短暂的旅行&#xff0c;你会选择哪里呢&#xff1f;春天的照片又该如何拍呢&#xff1f;看看下面的照片&#xff0c;或许能给你答案。照片的构图很巧妙&#xff0c;画面被分成两部分&#xff0c;一半湖泊&#xff0c;一半绿色树林。分开这些的是一条斜向的公路&#…

合并两个链表(自定义位置合并与有序合并)LeetCode--OJ题详解

图片: csdn 自定义位置合并 问题&#xff1a; 给两个链表 list1 和 list2 &#xff0c;它们包含的元素分别为 n 个和 m 个。 请你将 list1 中 下标从 a 到 b 的全部节点都删除&#xff0c;并将list2 接在被删除节点 的位置。 比如&#xff1a; 输入&#xff1a;list1 [1…

【STL】list剖析及模拟实现

✍作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;C 初识list 1. list基本概况 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立…

前端前沿web 3d可视化技术 ThreeJS学习全记录

前端前沿web 3d可视化技术 随着浏览器性能和网络带宽的提升 使得3D技术不再是桌面的专利 打破传统平面展示模式 前端方向主要流向的3D图形库包括Three.js和WebGL WebGL灵活高性能&#xff0c;但代码量大&#xff0c;难度大&#xff0c;需要掌握很多底层知识和数学知识 Threej…

卷积神经网络模型之——LeNet

目录LeNet模型参数介绍该网络特点关于C3与S2之间的连接关于最后的输出层子采样参考LeNet LeNet是一个用来识别手写数字的最经典的卷积神经网络&#xff0c;是Yann LeCun在1998年设计并提出的。Lenet的网络结构规模较小&#xff0c;但包含了卷积层、池化层、全连接层&#xff0…

Mr. Cappuccino的第49杯咖啡——冒泡APP(升级版)之基于Docker部署Gitlab

冒泡APP&#xff08;升级版&#xff09;之基于Docker部署Gitlab基于Docker安装Gitlab登录Gitlab创建Git项目上传代码使用Git命令切换Git地址使用IDE更换Git地址基于Docker安装Gitlab 查看beginor/gitlab-ce镜像版本 下载指定版本的镜像 docker pull beginor/gitlab-ce:11.3.0…

c# 源生成器

本文概述了 .NET Compiler Platform&#xff08;“Roslyn”&#xff09;SDK 附带的源生成器。 通过源生成器&#xff0c;C# 开发人员可以在编译用户代码时检查用户代码。 生成器可以动态创建新的 C# 源文件&#xff0c;这些文件将添加到用户的编译中。 这样&#xff0c;代码可以…

线程(一)

线程 1. 线程 定义&#xff1a;线程是进程的组成部分&#xff0c;不同的线程执行不同的任务&#xff0c;不同的功能模块&#xff0c;同时线程使用的资源师由进程管理&#xff0c;主要分配CPU和内存。 ​ 在进程中&#xff0c;线程执行的方式是抢占式执行操作&#xff0c;需要考…

33--Vue-前端开发-使用Vue脚手架快速搭建项目

一、vue脚手架搭建项目 node的安装: 官方下载,一路下一步 node命令类似于python npm命令类似于pip 使用npm安装第三方模块,速度慢一些,需换成淘宝镜像 以后用cmpm代替npm的使用 npm install -g cnpm --registry=https://registry.npm.taobao.org安装脚手架: cnpm inst…

汉诺塔--课后程序(Python程序开发案例教程-黑马程序员编著-第6章-课后作业)

实例3&#xff1a;汉诺塔 汉诺塔是一个可以使用递归解决的经典问题&#xff0c;它源于印度一个古老传说&#xff1a;大梵天创造世界的时候做了三根金刚石柱子&#xff0c;其中一根柱子从下往上按照从大到小的顺序摞着64片黄金圆盘&#xff0c;大梵天命令婆罗门把圆盘从下面开始…

C++回顾(二十)—— vector容器 和 deque容器

20.1 vector容器 20.1.1 vector容器简介 vector是将元素置于一个动态数组中加以管理的容器。vector可以随机存取元素&#xff08;支持索引值直接存取&#xff0c; 用[]操作符或at()方法&#xff09;。vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比…

es6的class(类)

目录 一、class&#xff08;类&#xff09;的语法 二、代码 三、效果 一、class&#xff08;类&#xff09;的语法 ES6 提供了更接近传统语言的写法&#xff0c;引入了 Class&#xff08;类&#xff09;这个概念&#xff0c;作为对象的模板。通过class关键字&#xff0c;可以…

Java基础(二):原码、反码、补码及进制之间的运算

Java基础系列文章 Java基础(一)&#xff1a;语言概述 Java基础(二)&#xff1a;原码、反码、补码及进制之间的运算 Java基础(三)&#xff1a;数据类型与进制 目录一、不同进制的表示方式二、二进制三、进制之间的转换四、byte的取值范围一、不同进制的表示方式 所有数字在计…

Leetcode 141.环形链表 142环形链表II

141环形链表 文章目录快慢指针快慢指针 代码思路&#xff1a; slow 和fast 指向 head slow走一步&#xff0c;fast走两步 没有环&#xff1a; fast每次走2步 &#xff0c;如果 fast 最终遇到NULL(链表中的元素是 偶数)或者fast->next(链表中的元素是 奇数)遇到NULL&#xf…