• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++基础之this指针与另一种“多态”

C++基础之this指针与另一种“多态”

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了C++基础之this指针与另一种“多态”等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

一、引入
定义一个类的对象,首先系统已经给这个对象分配了空间,然后会调用构造函数。

一个类有多个对象,当程序中调用对象的某个函数时,有可能要访问到这个对象的成员变量。
而对于同一个类的每一个对象,都是共享同一份类函数。对象有单独的变量,但是没有单独的函数,所以当调用函数时,系统必须让函数知道这是哪个对象的操作,从而确定成员变量是哪个对象的。
这种用于对成员变量归属对像进行区分的东西,就叫做this指针。事实上它就是对象的地址,这一点从反汇编出来的代码可以看到。

二、分析
1、测试代码:

2、反汇编分析
关键点截图如下:
(1)从图1可以发现this指针通过ECX寄存器,传递给了成员函数。this指针就是对象的地址。

图 1 Main函数

(2)从图 2可以发现访问对象的成员变量用的就是之前通过ECX传入的this指针。

 

图 2 show()函数

三、深入理解

通过截图及相关的资料,可以很清晰的知道在调用构造函数、show()函数之前的那个ECX就是this指针,也就是说这是一个验证性的实验,答案已经很清楚了,所要做的就是去动手体验一下。但是,假如我不懂C++、我不懂什么this指针,我一样可以发现这个叫做“this指针”的东西。通过OD的动态调试,当显示出了name时,逐步回溯可以发现name的源头是ECX。OD重新载入,查看在进入show()函数之前ECX是哪里来的,最终可以一步步的发现,ECX就是一个地址,这个地址里边的第一个值也是一个地址,指向一串字符串。再往上分析,进入show()上边的构造函数,可以发现里边有new操作,strcpy操作,这里就发现了字符串空间、内容的来源。至此,基本就分析完了。

通过这个过程可以发现很多C++的知识。如:对象的空间是在调用构造函数之前就分配好了的;对象里边没有函数;this指针通过寄存器ECX传递;通过声明定义的对象它的空间分配在栈中;等等这些跟系统或者C++有关联的知识。

但是,对于一个不懂C++的人看来,上面一段的体会都是没有的。从汇编指令看不出C++的思想,this指针不过是一个地址;对象不过是一些空间;构造函数、析构函数以及其它的函数,也不过是一堆指令的集合。

C++的同一个类定义出来的多个对象,从汇编指令看来是这样的:有很多块地址空间,它们有相同的大小。当不同的对象调用成员函数时,在汇编指令看来是:它们都call同一个地址,这个call指令其实里边是一个jmp指令,用于跳向某个位置,在call指令之前一般都会把一个地址放到ECX中,当然有时候会用堆栈或者其它寄存器。

C++的继承、多态、封装,对汇编程序员来说是看不出有什么神奇的,对于C++程序员来说那可就不同了,可以省去很多的工作,把很多事情都交给了编译器,让编译器自动给你搞定。

C++程序员所讨论的对象及其众多的特点、优点,最终还是变成了“低级”的指令,而且可能是效率低下的指令,即便如此,它的优点仍远大于缺点,它让编程变得容易、高效。

四、延伸

忽然想到了C++的多态,一句话“将子类类型的指针赋值给父类类型的指针”,多态是通过虚函数实现。对虚函数及其相关内容的原理、详细理解就不细说了。

说下我的简单理解,有一个基类A和子类B、C,有一个函数以基类A的指针为参数,然后在函数里头通过指针调用基类的成员函数。假如这个被调用的基类成员函数不是虚函数,那么是不可能实现多态的,因为翻译成汇编指令的时候,调用成员函数的这个地方是一个call指令,然后这个call指令跳到某个地方去执行,这是一个固定了的地址。通过定义为虚函数,调用成员函数的这个地方是通过虚函数表指针来确定调用哪个函数的,而虚函数表指针就放在对象的地址空间中,如果对象变了,那么虚函数表指针也变了,调用的函数也就不同了。对于那个以基类A的指针为参数的函数,指针即是对象的地址,如果传递的地址是子类B或者C的对象的地址,那么虚函数表指针也就不同了,调用的成员函数也就不同了。

这就是多态,这种多态使得调用同一个函数,因为传递参数的不同而显示出差异,参数可以是基类对象或者众多不同的子类对象。它们的差异是类与类之间的。

有虚函数的对象的内存布局,比没有虚函数的对象多了一个指向虚函数表的指针。因为虚函数的调用是通过虚函数表指针来实现的,所以有了多态。

再考虑一下C++的this指针,一个类中的成员函数,依据this指针来区分不同的对象,也就是说根据this指针实现了访问不同的对象的成员变量。

这是否也是多态的一种表现?这里所说的多态已经不是那个“父类指针指向子类对象”的教条了,而是体现在同一个类的不同对象之间,调用同一个成员函数

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-28理解数据结构
  • 2017-05-28C语言 位运算详解及示例代码
  • 2017-05-28c语言网络编程-标准步骤(比较简单)
  • 2017-05-28C与C++动态分配二维数组的实现方法
  • 2017-05-28简单的socket编程入门示例
  • 2017-05-28C++实现动态分配const对象实例
  • 2017-05-28c语言实现冒泡排序、希尔排序等多种算法示例
  • 2017-05-28C++设计模式之工厂方法模式
  • 2022-04-30C语言代码中的空白符
  • 2017-05-28c++中template对字符串的处理方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++实现类似延时停顿的打字效果
    • 基于memset()函数的深入理解
    • 浅析C语言中的setjmp与longjmp函数
    • 数据结构顺序表操作示例
    • 深入分析C中不安全的sprintf与strcpy
    • 深入线性时间复杂度求数组中第K大数的方法详解
    • 详解C++中StringBuilder类的实现及其性能优化
    • assert断言函数
    • C++交换指针实例
    • 浅谈C语言之字符串处理函数

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有