先问一个问题,在C++里,成员函数里的this指针和调用此函数的对象地址总是一样的吗?如果你的回答是:不一定。那么至少你是个老手吧,下面的内容你就不用看了;如果你的回答是:是啊,那么强烈建议你看看下面的内容。
非静态成员函数,无论是不是虚函数,都隐藏了一个this指针参数。这个参数的目的就是给函数提供一个基地址,以便于函数体内能找到对象的成员变量。那非静态成员函数是如何根据this指针找到成员变量的呢?直接看例子吧
1没有虚表的情况
那么函数F1的实现伪代码为:
*(this+&A::x-1) = 1;
*(this+&A::y-1) = 2;
其中&A::x是成员x的偏移+1,&A::y是成员y的偏移+1,这可是C++基本语法的知识,希望你知道,呵呵。可这些偏移量是相对应那里的偏移呢,是对象地址吗,答案是NO。是相对于第一个成员变量的偏移,这对于有些对象也许没有差别,但是对于有虚表的类的对象,就有差别了。这些偏移在编译期间就是确定了的。对于本例在VC++2010下&A::x,值为1, &A::y,值为5。为什么不是0,4,请看《Inside The C++ Object Model》。
所以,对于找到成员变量,需要进一步确定的只有this的值。程序运行结果如下:
可见此例中,对象的地址与this指针的地址相同,内存图如下所示。
2有一个虚表的情况
此时函数F1的实现伪代码为:
*(this+4+&A::x-1) = 1; //+4是因为存在虚表指针
*(this+4+&A::y-1) = 2; //+4是因为存在虚表指针
程序运行结果如下:
内存布局如下:
结论:this的值和对象地址相同,成员变量偏移量不因虚表指针存在而改变。带虚表的类的成员函数对成员变量的寻址方式不同,增加一个+4。
3单继承的情况
运行结果:
内存布局:
结论:this指针的值受两个因素确定,一是对象的地址,二是定义成员函数的类。This指向的是对象内,定义该方法的类得subobject。
4 多继承的情况
先看A没有虚函数,B有虚函数的情况
结果:
内存布局:
再看,如果A,B都有虚函数的情况。
代码:
结果:
内存布局:
结论:再一次验证了this指针的值的确定方法,this始终要保证指向定义了该成员函数的类得subobject。因为C++保证base class subobject与base class object完全对应,从而保证了成员函数能根据成员变量在定义了该变量的类中的偏移寻址。
分享到:
相关推荐
C++ 内存布局虚继承 ---Empty virtual base classs (空虚基类).doc
C++对象内存池 ---- C++侦探改写.rar
c++运行库2015-2019
如何让一个应用程序一直在后台运行? - C++ Builder - Windows SDK-API.mht
Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-C++Dev-...
c++ 标准不规定 c++ 实现的时候的对象的具体的内存布局,除了在某些方面有小的限制以外,c++ 对象在内存里面的布局完全是由编译器自行决定,这里只是讨论 vc++ .net 2003 build 7.1.3091 的实现方式.
C++程序设计-原理-与-实践第2版—进阶篇
数据结构-C++程序 线性表的线性存储例子-在dev c++平台运行正常,用于教学使用
c++继承中的内存布局 - 开源中国社区
Visual C++程序设计学习笔记(1-12 源码)Visual C++程序设计学习笔记(1-12 源码)Visual C++程序设计学习笔记(1-12 源码)
介绍如何在windows下运行QT程序 - C-C++ - 工具平台和程序库
Visual C++程序设计教程-梁建武-电子教案
c++程序设计初学者辅导书--易学c++c++程序设计初学者辅导书--易学c++
C++程序设计语言1-3部分 pdf
C++ 程序设计实验报告----车辆信息管理系统
C++程序设计初学者辅导书--易学C++
C++程序设计训练.孙甲松-2004 考试急用哈,贡献给大家
《Visual C++程序设计》-王永国-电子教案-6002.rar
Visual C++程序设计案例教程-张荣梅-源代码-第五章