来源

陈皓博客:

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");
}

关于内存布局的查看 可以在项目属性中的命令行中输入相关查看命令 也可以打开命令提示符进入对应文件输入

硬核内容转载—— 虚函数表解析 对象的内存布局硬核内容转载—— 虚函数表解析 对象的内存布局

 

相关文章: