0x02虚函数分析
来源:互联网 发布:网络空间的定义 编辑:程序博客网 时间:2024/06/06 02:29
#include <iostream>using namespace std;class Base1 {public: virtual void fun() { cout << "Base1::fun" << endl; } virtual void foo() { cout << "Base1::foo" << endl; } Base1() { printf("Base1\n"); } ~Base1() { printf("~Base1\n"); }};class Base2 {public: virtual void fun() { cout << "Base2::fun" << endl; } virtual void foo() { cout << "Base2::foo" << endl; } Base2() { printf("Base2\n"); } ~Base2() { printf("~Base2\n"); }};class Derive : public Base1, public Base2{public: virtual void fun() { cout << "Derive::fun" << endl; } virtual void foo1() { cout << "Derive::foo1" << endl; } Derive() { printf("Derive\n"); } ~Derive() { printf("~Derive\n"); }};int main(){ Derive d; Base1 *b1 = &d; b1->fun(); b1->foo(); Base2 *b2 = &d; b2->fun(); b2->foo(); return 0;}
根据继承关系的顺序,首先调用了基类Base1的构造函数。在调用另一个基类Base2时, 并不是直接将对象的首地址作为this指针传递,而是向后调整了基类Base1的大小,以调整后的地址值作为this指针,最后再调用基类Base2的构造函数。
由于有了两个基类,因此子类在继承时也将他们的虚表指针一起继承了过来,也就有了两个虚表指针。在多继承中,派生类虚表指针的个数取决于所继承的基类个数。
在转换Base2指针时,je short 001A65E5会调整首地址并跳过第一个基类所占用的空间。
由于具有多个同级的基类,因此早派生类中产生了多个虚表指针。在对基类进行析构时,需要设置this指针,用于调用基类的析构函数。由于具有多个基类,当在析构的过程中调用各个基类的析构函数时,传递的首地址将有所不同,编译器会根据每个基类在对象中占用的空间位置,对应地传入各个基类部分首地址作为this指针。
总结:
单继承:
- 在类对象占用的内存空间中,只保存一份虚表指针。
- 由于只有一个虚表指针,对应的也只有一个虚表。
- 虚表中各项保存了类中各虚函数的首地址。
- 构造时先构造基类,在构造自身,并且只调用一次基类构造函数。
- 析构时先析构自身,在析构基类,并且只调用一次基类析构函数。
多重继承类:
- 在类对象中所占的内存空间中,根据继承基类的个数保存对应的虚表指针。
- 根据所保存的虚表指针的个数,对应产生相应个数的虚表。
- 构造时需要调用多个基类构造函数。
- 转换基类指针时,需要调转到对应的首地址。
- 构造时先构造继承列表中第一个基类,然后依次调用到最后一个继承的基类构造函数
- 析构时先析构自身,然后以与构造函数相反的顺序调用所有基类的析构函数。
0 0
- 0x02虚函数分析
- 【J2SE归档总结】0x02 函数
- 逆向工程 0x02
- 0x02 开始操作
- [7]复用类0X02
- 程序员笑话0X02
- 【锋利的JQuery】0x02 JQuery选择器
- 【Div+CSS笔记】 0x02 css入门
- [Google EarlGrey] 0x02 API 简介
- Java 学习笔记(0x02) 运算符
- [6]访问控制权限 0X02
- ModBus协议-功能码-0x02
- 从0开始学Python--0x02. 启动Python
- Coursera-Machine Learning 之 Logistic Regression (逻辑回归)-0x02
- 用Golang写一个搜索引擎(0x02)
- 【java】arcII码为0x01,0x02作为分隔符
- xmd:AP transaction timeout: ACK = 0x01, expected=0x02)
- 教女友学习机器学习0X02——逻辑回归
- iOS开发之移动直播技术秒开、直播优化经验、直播问题解析、直播知识解惑
- Linux编程基础——GDB(设置断点)
- 顺序表_循环左移
- IOS改变TABBAR高度、背景颜色
- Python中pass、continue、break、exit()的区别
- 0x02虚函数分析
- Android 混淆问题
- HashMap实现原理及源码分析
- 异或运算实现简单的字符串加密和解密
- leetcode03-Longest Substring Without Repeating Characters之Java版本
- hadoop安装01
- 九度 OJ 1066:字符串排序
- 常用排序算法之希尔排序
- Java类的加载顺序