this指针的调整
我们先来看一段代码:
#include <iostream> using namespace std;
class A
{
public:
int a;
A( )
{
printf("A:A()的this指针是%p\n", this);
} void funcA( )
{
printf("A:funcA()的this指针是%p\n", this);
}
}; class B
{
public:
int b;
B( )
{
printf("B:B()的this指针是%p\n", this);
} void funcB( )
{
printf("B:funcB()的this指针是%p\n", this);
}
}; class C :public A, public B
{
public:
int c;
C( )
{
printf("C:C()的this指针是%p\n", this);
}
void funcC()
{
printf("C:funcC()的this指针是%p\n", this);
}
}; int main()
{
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
cout << sizeof(C) << endl; C cobj; cobj.funcA();
cobj.funcB();
cobj.funcC();
return ;
}
运行结果为:
第一个基类子对象A的起始地址是与派生类对象C是重合的。我们来看一张图片:
上图演示了this指针是如何调整的。在派生类的对象中,基类是作为派生类的子对象存在的,称为基类子对象,当派生类只继承于一个基类时,基类子对象的起始地址是与派生类对象相同的,而当派生类同时继承于多个基类时(多重继承,这里暂时不考虑虚拟继承)
第一个基类子对象的起始地址是与派生类对象重合的,而后续基类子对象的起始地址与派生类对象依次相差前面的基类子对象的长度,比如,D同时派生于A、B、C。D对象的起始地址是0,那么A子对象的起始地址也是0,B子对象的起始地址是0+sizeof(A),而C对象的起始地址为0 + sizeof(A) + sizeof(B)。上面的例子C类派生于A,B。C类对象的地址是006FFD4C,那么A子对象的起始地址和C类对象的起始地址是一样的为006FFD4C,B类对象的起始地址为006FFD4C + sizeof(A) = 006FFD4C + 4 = 006FFD50
如果我们把程修改成如下,输入结果会怎么样呢?
#include <iostream> using namespace std;
class A
{
public:
int a;
A( )
{
printf("A:A()的this指针是%p\n", this);
} void funcA( )
{
printf("A:funcA()的this指针是%p\n", this);
}
}; class B
{
public:
int b;
B( )
{
printf("B:B()的this指针是%p\n", this);
} void funcB( )
{
printf("B:funcB()的this指针是%p\n", this);
}
}; class C :public A, public B
{
public:
int c;
C( )
{
printf("C:C()的this指针是%p\n", this);
}
void funcC()
{
printf("C:funcC()的this指针是%p\n", this);
}
void funcB()
{
printf("C:funcB()的this指针是%p\n", this); //新增加的代码
}
}; int main()
{
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
cout << sizeof(C) << endl; C cobj; cobj.funcA();
cobj.funcB();
cobj.funcC();
return ;
}
输出结果为:
可以看到,此时三个值都相同了,C类override基类子对象B的funcB函数,此时funB()中的this指针指向C对象的起始地址。
this指针的调整的更多相关文章
- 《C与指针》第十一章练习
本章问题 1.在你的系统中,你能够声明的静态数组最大的长度能达到多少?使用动态内存分配,你最大能获取的内存块有多少? answer: This will vary from system to sys ...
- c/c++: c++继承 内存分布 虚表 虚指针 (转)
http://www.cnblogs.com/DylanWind/archive/2009/01/12/1373919.html 前部分原创,转载请注明出处,谢谢! class Base { pu ...
- 从汇编看c++成员函数指针(二)
下面先看一段c++源码: #include <cstdio> using namespace std; class X { public: virtual int get1() { ; } ...
- 从汇编看c++多重继承中this指针的变化
先来看一下下面的c++源码: #include <iostream> using namespace std; class X { public: virtual void print1( ...
- C语言精要总结-指针系列(一)
考虑到指针内容繁多,这里将指针作为一个系列,从简入繁,一点一点深挖并掌握这C语言的精华.初步计划如下 此文为指针系列第一篇: C语言精要总结-指针系列(一) 内存与地址 我们可以把内存看做一排连续的房 ...
- 虚函数指针sizeof不为sizeof(void*)
ref:http://bbs.csdn.net/topics/360249561 一个继承了两个虚基类又增加了自己的一个虚函数pif的类,sizeof(指向pif的指针)竟然是8(X86).我是从这里 ...
- 成员函数指针与高效C++委托 (delegate)
下载实例源代码 - 18.5 Kb 下载开发包库文件 - 18.6 Kb 概要 很遗憾, C++ 标准中没能提供面向对象的函数指针. 面向对象的函数指针也被称为闭包(closures) 或委托(del ...
- 关于C++中的非静态类成员函数指针
昨天发现了一个问题,就是使用对类中的非静态成员函数使用std::bind时,不能像普通函数一样直接传递函数名,而是必须显式地调用&(取地址),于是引申出我们今天的问题:非静态类成员函数指针和普 ...
- SplayTree伸展树的非递归实现(自底向上)
Splay Tree 是二叉查找树的一种,它与平衡二叉树.红黑树不同的是,Splay Tree从不强制地保持自身的平衡,每当查找到某个节点n的时候,在返回节点n的同时,Splay Tree会将节点n旋 ...
随机推荐
- bzoj 4650(洛谷 1117) [Noi2016]优秀的拆分——枚举长度的关键点+后缀数组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4650 https://www.luogu.org/problemnew/show/P1117 ...
- Win7 搭建pptpvpn服务器方法
打开网络与共享中心 选择更改适配器设置 选择菜单文件选项(若无菜单栏,可以按一下alt键就会显示出来的) 选择新建传入链接 选择需要哪些用户可以访问vpn服务器,把勾搭上,点击下一步 注意此处的通过i ...
- .NET : Func委托和Action委托
其实他们两个都是委托[代理]的简写形式. 一.[action<>]指定那些只有输入参数,没有返回值的委托 Delegate的代码: public delegate void myDeleg ...
- linux中uptime命令查看linux系统负载
阅读目录 uptime cat /proc/loadavg 何为系统负载呢? 进阶参考 uptime 另外还有一个参数 -V(大写),是用来查询版本的 [appdeploy@CNSZ22PL0088: ...
- css属性所对应js属性
document.getElementById("xx").style.xxx中的所有属性是什么,css对应js: 盒子标签和属性对照 CSS语法(不区分大小写) JavaScri ...
- [转]C#调用Excel VBA宏
[转载自]http://www.shangxueba.com/jingyan/95031.html 附上一段原创常用代码 计算列标题字符串 Function CalcColumn(ByVal c As ...
- Appium+python自动化8-Appium Python API
Appium+python自动化8-AppiumPython API 前言: Appium Python API全集,不知道哪个大神整理的,这里贴出来分享给大家. 1.contexts conte ...
- iOS 一些琐碎的知识点
1. Xcode左边导航栏中,类文件后面的标记"A""M""?"符号的含义 M = Locally modified 文件已被修改 U = ...
- Linux操作系统,服务器端的主流
1.无意之间,一直使用的Windows,其实也是在Unix的基础之上开发的,什么xp,win7等都是,就是Unix的一些堆砌,其实这样说也不对.但是windows的复杂程度比Linux要复杂,因为Wi ...
- Node.js 介绍及安装
Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装.本文详细介绍了No ...