C++虚继承中的对象内存布局
来源:互联网 发布:windows更新消失 编辑:程序博客网 时间:2024/05/21 09:23
钻石型虚拟继承
虚继承是为了解决多继承中的数据冗余而出现的。
eg:
#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>using namespace std;typedef void(*FUNC)();class Base{public:virtual void fun1(){cout << "Base::fun1()" << endl;}public:int _b;};class Parent1:virtual public Base{public:virtual void fun1(){cout << "Parent1::fun1()" << endl;}virtual void fun2(){cout << "Parent1::fun2()" << endl;}public:int _p1;};class Parent2 :virtual public Base{public:virtual void fun1(){cout << "Parent2::fun1()" << endl;}virtual void fun3(){cout << "Parent2::fun3()" << endl;}public:int _p2;};class Child : public Parent1,public Parent2{public:virtual void fun1(){cout << "Child::fun1()" << endl;}virtual void fun2(){cout << "Child::fun2()" << endl;}virtual void fun3(){cout << "Child::fun3()" << endl;}virtual void fun4(){cout << "Child::fun4()" << endl;}public:int _c;};void PrintVfptr(int* vptr)//打印虚函数表{cout << "虚函数表: " << vptr << endl;for (int i = 0; vptr[i] != 0; ++i){printf("第%d个虚函数:%p >> ", i, vptr[i]);FUNC f = (FUNC)(vptr[i]);f();}}void PrintfMove(int* vbptr)//打印偏移量{cout << "偏移量 >: " << endl;for (int i = 0; vbptr[i] != 0; ++i){printf("第%d个虚函数:%d\n", i, vbptr[i]);}cout << endl;}void Test(){Child c;c._b = 1;c._p1 = 2;c._p2 = 3;c._c = 4;cout << "sizeof(Base)::" << sizeof(Base) << endl;cout << "sizeof(Parent1)::" << sizeof(Parent1) << endl;cout << "sizeof(Parent2)::" << sizeof(Parent2) << endl;cout << "sizeof(Child)::" << sizeof(Child) << endl;int* cAddress = (int*)&c;cout << "Parent1::";int* tmpP1 = (int*)(*cAddress);PrintVfptr(tmpP1);cout << "Parent1::";int* moveP1 = (int*)(*(cAddress + 1));PrintfMove(moveP1);cout << endl;cout << "Parent2::";int* tmpP2 = (int*)(*(cAddress + 3));PrintVfptr(tmpP2);cout << endl;cout << "Parent1::";int* moveP2 = (int*)(*(cAddress + 4));PrintfMove(moveP2);cout << endl;int* tmpBase = (int*)(*(cAddress + 7));PrintVfptr(tmpBase);cout << endl;}int main(){Test();system("pause");return 0;}
程序运行结果:
对象在内存中的布局:
大家可以发现:
0x0014F8F8 + 0xFFFFFFFC(-4) = 0x0014F8F4, 0x0014F8F8 + 0x00000018 = 0x0014F910;
0x0014F904 + 0xFFFFFFFC(-4) = 0x0014F900, 0x0014F904 + 0x0000000c = 0x0014F910.
所以,有以下结论:
在虚继承时,类中会自动加一个指针(VBPTR),该变量指向一个全类共享的偏移量表,如果本类有虚函数,那么第一项记录着当前子对象相对与虚基类表指针(VBPTR指针)的偏移,是FF FF FF FC(也就是-4),如果没有则是零;第二项起是被继承的基类(上述例子为Base类)子对象相对于VBPTR指针的偏移量。
0 0
- C++-对象继承中的内存布局
- C++虚继承中的对象内存布局
- C++对象内存布局:单继承,多继承,虚继承
- c++虚继承对象的内存布局
- c++虚继承对象的内存布局
- c++虚继承对象的内存布局
- c++虚继承对象的内存布局
- c++虚继承对象的内存布局
- c++虚继承对象的内存布局
- 虚继承内存布局@c++对象模型
- c++虚继承对象的内存布局
- c++虚继承对象的内存布局
- 【c++】深度探索虚继承内存布局
- C++ 多继承和虚继承的内存布局
- c++继承中的内存布局
- c++继承中的内存布局
- c++继承中的内存布局
- c++继承中的内存布局
- C语言的注释与C++注释的转换
- 两个链表的合并
- 单链表的操作
- 单继承与多继承中的虚函数表和虚函数指针
- Hyper-V Server故障转移群集安装
- C++虚继承中的对象内存布局
- 智能指针的模拟实现 auto_ptr scoped_ptr shared_ptr
- [并查集 树] BZOJ 4551 [Tjoi2016&Heoi2016]树
- 智能指针的模拟实现shared_ptr 循环引用 定置删除器
- 利用栈计算算数表达式的值
- 稀疏矩阵的压缩存储与转置
- (学习笔记)从引用参数谈到左右值
- 大数据的运算加减乘除
- 迷宫问题并求最短路径