来源
陈皓博客:
C++ 虚函数表解析 https://blog.csdn.net/haoel/article/details/1948051
C++ 对象的内存布局(上):https://blog.csdn.net/haoel/article/details/3081328
C++ 对象的内存布局(下):https://blog.csdn.net/haoel/article/details/3081385
来源:
Fred^_^博客:
【C++拾遗】 从内存布局看C++虚继承的实现原理 :https://blog.csdn.net/xiejingfa/article/details/48028491
【C++拾遗】 C++虚函数实现原理 https://blog.csdn.net/Xiejingfa/article/details/50454819
来源:
用心倾听博客:
虚函数表存放在哪里 :https://blog.csdn.net/jiary5201314/article/details/52627630
/**
虚继承(虚基类)
*/
#include <iostream>
// 基类A
class A
{
public:
int dataA;
};
class B : virtual public A
{
public:
int dataB;
};
class C : virtual public A
{
public:
int dataC;
};
class D : public B, public C
{
public:
int dataD;
};
int main()
{
D* d = new D;
d->dataA = 10;
d->dataB = 100;
d->dataC = 1000;
d->dataD = 10000;
B* b = d; // 转化为基类B
C* c = d; // 转化为基类C
A* a = d; //转化为基类A
A* fromB = (B*)d;
A* fromC = (C*)d;
// 测试 类D各父类的内存地址
std::cout << "a address: " << a << std::endl;
std::cout << "d address : " << d << std::endl;
std::cout << "b address : " << b << std::endl;
std::cout << "c address : " << c << std::endl;
// 类B和C 中A的内存分布
std::cout << "fromB address: " << fromB << std::endl;
std::cout << "fromC address: " << fromC << std::endl;
std::cout << std::endl;
// 类D中的B虚基类表地址
std::cout << "vbptr address: " << (int*)d << std::endl;
// 虚表中记录了vbptr与本类的偏移地址
std::cout << " [0] => " << *(int*)(*(int*)d) << std::endl;
std::cout << " [1] => " << *(((int*)(*(int*)d)) + 1) << std::endl; // 偏移量20
// 类D中从类B中继承而来的dataB的值
std::cout << "dataB value : " << *((int*)d + 1) << std::endl;
// 类D中的C的虚基类表地址
std::cout << "vbptr address: " << ((int*)d + 2) << std::endl;
// 虚表中记录了vbptr与本类的偏移地址
std::cout << " [0] => " << *(int*)(*((int*)d + 2)) << std::endl;
std::cout << " [1] => " << *((int*)(*((int*)d + 2)) + 1) << std::endl; // 偏移量12
// 类D中从类C中继承而来的dataC的值
std::cout << "dataC value : " << *((int*)d + 3) << std::endl;
// 类D中dataD的值
std::cout << "dataD value : " << *((int*)d + 4) << std::endl;
// 类D中从类A中继承而来的dataA的值
std::cout << "dataA value : " << *((int*)d + 5) << std::endl;
//各类的地址
std::cout << "dataB address :" << ((int*)d ) << std::endl;
std::cout << "dataC address :" << ((int*)d + 3) << std::endl;
std::cout << "dataD address :" << ((int*)d + 4) << std::endl;
std::cout << "dataA address :" << ((int*)d + 5) << std::endl;
system("pause");
}
关于内存布局的查看 可以在项目属性中的命令行中输入相关查看命令 也可以打开命令提示符进入对应文件输入