C++对象模型(19)-- 函数语义学:成员函数

1、普通成员函数的调用

1.1 调用方式的转换

为了提高普通成员函数的调用效率,在C++中,对普通成员函数的调用,会转换成对全局函数的调用。

假如有下面所示的成员函数:

class Test {
public:int m_i;int func(int a) {m_i += a;return m_i;}
};

在编译时会经历下面几个步骤:

(1)把对象的首地址作为参数,传递给函数。

int func(Test *const this, int a) {}

(2)对非静态成员变量的调用,改成通过this指针来调用。

int func(Test *const this, int a) {this->m_i += a;return this->m_i;     
}

(3)对函数名进行name mangling操作,通过函数名和其参数类型生成唯一标识符,来区分不同的函数。

int _ZN4Test4funcEi(Test *const this, int a){}

1.2 代码演示

(1)

在main()函数中加入调用函数func()的代码:

int main() {Test test;int ret = test.func(6);
}

然后把断点设在:int ret = test.func(6); 运行程序后,查看反汇编代码(VS2019):

简单分析下汇编语言的意思:

(1)push 6:把参数6入栈。

(2)lea ecx, [test]:把test写入ecx。

这2行其实是参数传递。

(3)call Test::func(05C12D0h):调用函数func。

(4)move dword ptr [ret], eax:把eax的值赋给ret。

从这些代码可以看到,函数的调用流程可分成3个阶段:参数传递、调用函数call、处理返回值。

在反汇编的“地址(A)”窗口输入函数func的地址:05C12D0h,回车后查看函数func的反汇编代码:

这段汇编的细节不去深究,但我们可以看到有[this]字样,可以知道函数在具体执行时用到了this指针。

所以对func函数的调用转换可以用下图表示:

如果用指针方式调用成员函数:

Test* pTest;
int ret = pTest->func(6);

则对func函数的调用转换是这样的:

(2)把代码在linux上编译后,用nm命令查看可执行文件的信息。

linux下编译:g++ ch19.cpp -o ch19

用nm命令查看可执行文件:nm ch19

可以看到,func函数被转换成了_ZN4Test4funcEi。

2、静态成员函数的调用

对于静态成员函数的调用,无论用对象名来调用,还是用对象指针来调用,效果都是一样的,都会被编译器转换成一般的针对普通函数(非成员函数)的调用形式。

静态成员函数是跟着类走的,所有调用静态成员函数时编译器是不会插入this作为形参的。

假如类Test有一个static成员函数:

static void stfunc() { }

则可以用下面的方法来调用此静态成员函数:

Test test;
test.stfunc();Test::stfunc();Test* pTest;
pTest->stfunc();

静态成员函数有以下特点:

(1)静态成员函数没有this指针,这点最重要。

(2)无法直接存取类中普通的非静态成员变量,因为非静态成员变量是通过this指针来操作的。

(3)静态成员函数不能在后面使用const,也不能设置为virtual。

(4)可以用类对象调用,但不非一定要用类对象调用。

(5)静态成员函数等同于非成员函数,需要提供回调函数的这种场合,可以将静态成员函数作为回调函数。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】类型转换

一、C语言中的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与 接收返回值类型不一致时,就需要发生类型转化。 C语言中总共有两种形式的类型转换:隐式类型转换和显式…

【三】kubernetes kuboard部署分布式系统

#服务器 #部署 #云原生 #k8s 目录 一、前言二、搭建docker私有仓库三、系统搭建1、NFS部署1)部署nfs server (192.168.16.200)2)部署nfs client (全部节点)3)在Kuboard中创建 NFS 存储类 2、创建命名空间3、添加docker密文4、创建…

解决 Could not build wheels for pandas, which is required to install pyproject.toml-based projects

最近在学习李沐老师的深度学习的课程,在安装 d2l 时, pip install d2l0.17.6遇到了问题: ERROR: Could not build wheels for pandas, which is required to install pyproject.toml-based projects 由于我忘记截错误的图了,在论…

基于SSM的图书商城网站设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

Linux下Samba服务安装及启用全攻略

Linux下Samba服务安装及启用全攻略 前言一、安装SSH Server二、安装Samba Server1.安装net-tool2.建立账号的samba3.windows通过Samba与linux共享文件4.使用远程工具登录Linux 总结 前言 提示:本文详解了在Linux系统下如何安装和启用Samba服务,涵盖了从…

5、Kafka集成 SpringBoot

SpringBoot 是一个在 JavaEE 开发中非常常用的组件。可以用于 Kafka 的生产者,也可以 用于 SpringBoot 的消费者。 1)在 IDEA 中安装 lombok 插件 在 Plugins 下搜索 lombok 然后在线安装即可,安装后注意重启 2)SpringBoot 环境准…

三十七、【进阶】SQL的explain

1、explain 2、基础使用 在使用explain关键字时,只需要在所执行语句前加上explain即可 mysql> explain select * from stu where id3; ---------------------------------------------------------------------------------------------------------- | id | s…

shell学习脚本04(小滴课堂)

他就可以直接读出来了。不需要在sh后面加参数。 可以用-s隐藏内容: 可以用-t进行指定几秒后显示。 -n限制内容长度。 输入到长度为5自动打印。 我们把-s放到-p后面的话: 这样会出错。 如果最后加5m会一直闪烁。 大家可以按照需求自行使用。

Qt第六十五章:自定义菜单栏的隐藏、弹出

目录 一、效果图 二、qtDesigner 三、ui文件如下: 四、代码 一、效果图 二、qtDesigner 原理是利用属性动画来控制QFrame的minimumWidth属性。 ①先拖出相应的控件 ②布局一下 ③填上一些样式 相关QSS background-color: rgb(238, 242, 255); border:2px sol…

雪数据同化系统Snow Data Assimilation System数据集

雪数据同化系统(SNODAS) 雪资料同化系统(SNODAS)是国家水文遥感业务中心(NOHRSC)精心开发的综合建模和资料同化系统。其主要目标是提供高度准确的积雪和相关参数估计,作为水文建模和分析的重要…

如何正确维护实验室超声波清洗机

实验室一直被视作一个严谨且严肃的场所,在其中所做的试验都需要遵照一定流程,所用的设备也经过了细致化挑选,例如实验室超声波清洗机,其性能远强于普通类别的清洗机。专门负责采购的实验室人员,通常会对质量优服务好的…

居民小区电动汽车有序充电策略研究

摘 要:针对电动汽车在居民小区无序充电对电网系统产生严重隐患及充电间时过长问题,提出一种采用延迟充电的电动汽车有序充电控制策略,并在分析国内外电动汽车有序充电的研究现状后,设计了居民小区电动汽车有序充电策略的总体框架。…

Linux常用命令——clock命令

在线Linux命令查询工具 clock 用于调整 RTC 时间。 补充说明 clock命令用于调整 RTC 时间。 RTC 是电脑内建的硬件时间,执行这项指令可以显示现在时刻,调整硬件时钟的时间,将系统时间设成与硬件时钟之时间一致,或是把系统时间…

【网络爬虫 | Python】数字货币ok链上bitcoin大额交易实时爬取,存入 mysql 数据库

文章目录 一、网站分析二、js 逆向获取 X-Apikey三、python 调用 js 获取 X-Apikey四、python 爬虫部分五、mysql 数据库、日志、配置文件、目录结构六、结尾 一、网站分析 oklink:https://www.oklink.com/ btc 大额交易:https://www.oklink.com/btc/tx-…

初始Redis 分布式结构的发展演变

目录 Redis的特点和使用场景 分布式系统的引入 单机系统 分布式系统 应用服务器的增多(处理更多的请求) 数据库读写分离(数据服务器的增多) 引入缓存 应对更大的数据量 业务拆分:微服务 Redis的特点和使用场景 我们先来…

Notepad++正则查询替换操作

Notepad编辑器查找功能非常强大,本处记录一些实战中常用到复杂查询替换操作。 注意:如果是重要文件,替换操作前最好备份;当前一个操作后也可以用ctrlz恢复。 查找重复行 用查找(ctrlf)功能,用正则表达式模式匹配。 查…

YOLOV8目标检测——模型训练

文章目录 1下载yolov8([网址](https://github.com/ultralytics/ultralytics))2用pycharm打开文件3训练自己的YOLOV8数据集4run下运行完了之后没有best.pt文件5导出为onnx文件 本章内容主要解决如何训练自己的YOLOV8模型。 1下载yolov8(网址&a…

SpringCloud之OpenFeign调用解读

目录 基本介绍 引进 OpenFeign概述 OpenFeign作用 FeignClient EnableFeignClients Java代码实战 实战架构 父工程pom文件 teacher-service服务 student-service服务 测试 自定义配置 基本介绍 引进 如果我们利用RestTemplate发起远程调用的代码时会存在一些…

[ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹

本文收录于【#云计算入门与实践 - AWS】专栏中,收录 AWS 入门与实践相关博文。 本文同步于个人公众号:【云计算洞察】 更多关于云计算技术内容敬请关注:CSDN【#云计算入门与实践 - AWS】专栏。 本系列已更新博文: [ 云计算 | …

Openssl数据安全传输平台004:Socket C-API封装为C++类 / 服务端及客户端代码框架和实现

文章目录 0. 代码仓库1. 客户端C API2. 客户端C API的封装分析2.1 sckClient_init()和sckClient_destroy()2.2 sckClient_connect2.3 sckClient_closeconn()2.4 sckClient_send()2.5 sckClient_rev()2.6 sck_FreeMem 3. 客户端C API4. 服务端C API5. 服务端C6. 客户端和服务端代…