C++对象内存模型探究模型

C++对象内存模型探究模型


转载注明出处:https://www.zhihu.com/people/peng-cheng-17-51

作者:Cheng游戏开发

前言:

  • C++的基于继承关系动态多态特性可以允许父子继承关系的类之间重写函数
  • 编译器会在存在虚函数的对象中塞入一个虚表指针,指向一个虚表
  • 表内装了我们们所重写的虚函数
  • 还讨论了多继承下虚继承相关内容
  • 还有内存分布规则

目的:

探究虚表与虚函数在对象中的内存占用情况

前置知识

this指针的内部调整

代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Datainfo
{
	int** _ptr;
	string _dataInfo;
	void PrintSelf()
	{
		cout << _dataInfo;
		while (_dataInfo.size() < 40)
		{
			_dataInfo.append(" ");
			cout << ' ';
		}
		cout << _ptr << endl;
	}

};

bool GreaterSort(Datainfo& Left, Datainfo& Right)
{
	return Left._ptr < Right._ptr;
}

std::vector<Datainfo> StructDataInfo;

typedef void(*FUNC)();

void PrintVTable(int**& VTable)
{

	std::cout << " 虚表函数地址: " << VTable << std::endl;
	for (int i = 0; (VTable[i]) != NULL; ++i)
	{
		__try
		{


			FUNC f = (FUNC)VTable[i];
			f();


			printf("<-第%d个虚函数地址: 0X%x,\n", i, VTable[i]);
		}
		__except (1)
		{
			std::cout << " 虚表函数结束 " << std::endl;
			break;
		}


	}

	std::cout << std::endl;

}

void PrintAllData()
{
	std::cout << "输出所有" << endl;
	std::sort(StructDataInfo.begin(), StructDataInfo.end(), GreaterSort);

	for (auto var : StructDataInfo)
	{
		var.PrintSelf();
	}
}
class Interface_PointA 
{
public:

	void PrintInterface_PointA()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointA Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

	}

	int _a = 0;

	void PrintVPtrTableA()
	{
		std::cout << "Interface_PointA的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:

	virtual void Interface_PointA_1() {
		std::cout << " Interface_PointA::Interface_PointA_1 ";
	}

	virtual void BaseFunction() {
		std::cout << "Interface_PointA:: BaseFunction ";
	};


};
class Interface_PointB 
{
public:

	int _b = 0;

	void PrintInterface_PointB()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointB Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

	}

	void PrintVPtrTableB()
	{
		std::cout << "Interface_PointB的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:
	virtual void Interface_PointB_1() {
		std::cout << " Interface_PointB::Interface_PointB_1 ";
	}
	
	virtual void BaseFunction() {
		std::cout << "Interface_PointB:: BaseFunction ";
	};

};

class Point3D :public Interface_PointA, public Interface_PointB
{
public:
	void PrintPoint3D()
	{
		Datainfo NewData;
		NewData._dataInfo = "Point3D Start  this is:";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_Point3Data is :";
		NewData._ptr = (int**)&this->_Point3Data;
		StructDataInfo.push_back(NewData);

		PrintInterface_PointA();
		PrintInterface_PointB();
	}

	void PrintVPtrTablePoint3D()
	{
		std::cout << "Point3D的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}

	virtual void Interface_PointB_1() {
		std::cout << " Point3D::Interface_PointB_1 ";
	}

	virtual void Interface_PointA_1() {
		std::cout << " Point3D::Interface_PointA_1 ";
	}

	void PrintVPtrTable()
	{
		PrintVPtrTableB();
		PrintVPtrTableA();
		PrintVPtrTablePoint3D();
	}

	virtual void Point3D_1() {
		std::cout << " Point3D::Point3D_1 ";
	}

	virtual void Point3D_2() {
		std::cout << "Point3D:: Point3D_2 ";
	}
	
	int _Point3Data = 0;

	virtual void BaseFunction() override {
		std::cout << " Point3D::BaseFunction ";
	};

};

int main()
{

	Point3D TestChildInstance = Point3D();
	TestChildInstance.PrintPoint3D();
	std::cout << "sizeof(void*) is                 " << sizeof(void*) << std::endl;
	std::cout << "sizeof(int) is                   " << sizeof(int) << std::endl;
	std::cout << "sizeof(Point3D) is               " << sizeof(Point3D) << std::endl;
	PrintAllData();
	TestChildInstance.PrintVPtrTable();

	return 0;
}

在这里插入图片描述

总结:

我们可以看到在C++的继承关系
子类实例不同继承层里面的 this指针 其实是指向不同位置
一般都是指向对应继承父类开头位置

虚表指针与虚表

  • 我们可以看到,子类 Point3D基类 Interface_PointA 共用 了一个虚表指针,而且指向同一个虚表
  • 虚表一般占用的是每个类实例this 指针头 8 个字节
  • 在这种情况下,其实我们可以看到普通继承中其实是存在主次要关系的
  • 普通继承中主次要继承关系的决定因素:
    • 有虚指针的优先级更高
    • 同优先级按照继承顺序排
      在这里插入图片描述
验证普通继承关系是否存在主次要继承
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Datainfo
{
	int** _ptr;
	string _dataInfo;
	void PrintSelf()
	{
		cout << _dataInfo;
		while (_dataInfo.size() < 40)
		{
			_dataInfo.append(" ");
			cout << ' ';
		}
		cout << _ptr << endl;
	}

};

bool GreaterSort(Datainfo& Left, Datainfo& Right)
{
	return Left._ptr < Right._ptr;
}

std::vector<Datainfo> StructDataInfo;

typedef void(*FUNC)();

void PrintVTable(int**& VTable)
{

	std::cout << " 虚表函数地址: " << VTable << std::endl;
	for (int i = 0; (VTable[i]) != NULL; ++i)
	{
		__try
		{


			FUNC f = (FUNC)VTable[i];
			f();


			printf("<-第%d个虚函数地址: 0X%x,\n", i, VTable[i]);
		}
		__except (1)
		{
			std::cout << " 虚表函数结束 " << std::endl;
			break;
		}


	}

	std::cout << std::endl;

}

void PrintAllData()
{
	std::cout << "输出所有" << endl;
	std::sort(StructDataInfo.begin(), StructDataInfo.end(), GreaterSort);

	for (auto var : StructDataInfo)
	{
		var.PrintSelf();
	}
}
class Interface_PointA 
{
public:

	void PrintInterface_PointA()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointA Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

	}

	int _a = 0;

	void PrintVPtrTableA()
	{
		std::cout << "Interface_PointA的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:

	


};
class Interface_PointB 
{
public:

	int _b = 0;

	void PrintInterface_PointB()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointB Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

	}

	void PrintVPtrTableB()
	{
		std::cout << "Interface_PointB的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:
	virtual void Interface_PointB_1() {
		std::cout << " Interface_PointB::Interface_PointB_1 ";
	}
	
	virtual void BaseFunction() {
		std::cout << "Interface_PointB:: BaseFunction ";
	};

};
class Interface_PointC
{
public:

	int _c = 0;

	void PrintInterface_PointC()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointC Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _c is :";
		NewData._ptr = (int**)&this->_c;
		StructDataInfo.push_back(NewData);

	}

	void PrintVPtrTableC()
	{
		std::cout << "Interface_PointC的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:
	virtual void Interface_PointC_1() {
		std::cout << " Interface_PointC::Interface_PointB_1 ";
	}

	virtual void BaseFunction() {
		std::cout << "Interface_PointC:: BaseFunction ";
	};

};
class Point3D :public Interface_PointA, public Interface_PointB, public Interface_PointC
{
public:
	void PrintPoint3D()
	{
		Datainfo NewData;
		NewData._dataInfo = "Point3D Start  this is:";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_Point3Data is :";
		NewData._ptr = (int**)&this->_Point3Data;
		StructDataInfo.push_back(NewData);

		PrintInterface_PointA();
		PrintInterface_PointB();
		PrintInterface_PointC();
	}

	void PrintVPtrTablePoint3D()
	{
		std::cout << "Point3D的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}

	virtual void Interface_PointB_1() {
		std::cout << " Point3D::Interface_PointB_1 ";
	}

	virtual void Interface_PointA_1() {
		std::cout << " Point3D::Interface_PointA_1 ";
	}

	void PrintVPtrTable()
	{
		PrintVPtrTableC();
		PrintVPtrTableB();
		PrintVPtrTableA();
		PrintVPtrTablePoint3D();
	}

	virtual void Point3D_1() {
		std::cout << " Point3D::Point3D_1 ";
	}

	virtual void Point3D_2() {
		std::cout << "Point3D:: Point3D_2 ";
	}
	
	int _Point3Data = 0;

	virtual void BaseFunction() override {
		std::cout << " Point3D::BaseFunction ";
	};
	virtual void Interface_PointC_1() {
		std::cout << " Interface_PointC::Interface_PointB_1 ";
	}
};

int main()
{

	Point3D TestChildInstance = Point3D();
	TestChildInstance.PrintPoint3D();
	std::cout << "sizeof(void*) is                 " << sizeof(void*) << std::endl;
	std::cout << "sizeof(int) is                   " << sizeof(int) << std::endl;
	std::cout << "sizeof(Point3D) is               " << sizeof(Point3D) << std::endl;
	PrintAllData();
	TestChildInstance.PrintVPtrTable();

	return 0;
}
普通继承中的内存顺序也取决于这个
  • 有虚指针的优先级更高
  • 同优先级按照继承顺序
    在这里插入图片描述
虚表指针的覆盖
虚表中的函数以什么规则出现的?出现在哪里?
  • 虚函数只会出现第一次被声明的类所拥有的虚表中
子类重写的话,重写到了哪里?为什么这么做?
  • 虚函数的重写会覆盖到每一个基类的持有这个函数的虚表中
为什么会这么做?

一切目的是为了兼容多态用法

class Interface_PointA
{
virtual void BaseFunction();
};
class Interface_PointB
{
virtual void BaseFunction();
};
class Point3D:Interface_PointA,Interface_PointB
{
virtual void BaseFunction();
};


Interface_PointA *p = new Point3D();
Interface_PointB *p1 = new Point3D();
p1->BaseFunction();

首先BaseFunctionInterface_PointAInterface_PointB的虚表中都存在
因为:
对于Interface_PointA来说,BaseFunction是在这个继承链上第一次出现的虚函数
对于Interface_PointB来说,BaseFunction是在这个继承链上第一次出现的虚函数

假设要调用 Interface_PointA 的指针 PBaseFunction
其实是调用子类重写过的 BaseFunction
在拿到 p 的时候,会根据其指针类型 Interface_PointA
找到其 this 指向的地方,再找到其虚表的对应的 BaseFunctionp1 也是如此。
所以 Point3DBaseFunction 直接覆盖到 Interface_PointAInterface_PointB 的虚表中
可以保证在不知道是什么具体子类实例是什么的情况下,正确调用到被重写的函数

内存分布会是什么样的呢?
  • 优先有虚函数的排布,之后排布没有虚函数的。
  • 都有虚函数同层基类之间按照继承顺序排序。
    在这里插入图片描述

虚继承的内存分布与寻址方式

虚继承的作用:保证菱形继承情况下,同名变量只有一个

虚继承表
  • 虚继承情况,虚表指针的位置
    • 如果在类开头没有虚函数表指针的话,虚继承表就占前8个字节
    • 如果在类开头有虚函数表指针的话,虚继承表指针排在虚函数表指针后面
  • 虚继承情况,虚表指针的内容(全虚继承)
    • 第一个值是当前虚表指针到当前的this指针的偏移量
    • 第二个是当前虚基类到其继承顺序继承下的最基类的距离
    • 之后的按照第二条规则往下排序,之后是最基类的上一层
    • 此顺序也顺应于内存排布
      举个例子:
class Point0
{
	int a;
};
class Point1 :virtual public Point0
{
	int a;
};
class Point21
{
	int a;
};
class Point22 :virtual public Point1
{
	int a;
};
class Point31 :virtual public Point21
{
	int a;
};
class Point32 :virtual public Point22
{
	int a;
};
class PointFinal:virtual public Point31, virtual public Point32
{
	int a;
};

在这里插入图片描述

分析
  • 内存分布:
  1. PointFinal 先虚继承 Point31
  2. Point31 虚继承 Point21 ,把最基类的 Point21 排到第二位,然后后面是 Point31
  3. 之后开始把第二条虚继承链开始塞入结构
  4. 先找到最基类 Point0 ,塞到 Point31 后面,然后是 Point0 的上一层 Point1
  5. 然后是 Point22 ,然后是再上一层的Point32
  • 虚表分析:
    PointFinal(vbptr)
    PointFinal的虚表中存着它所有虚父类的偏移量
    0 到自己的 this 偏移量
    16 到内存分布中第一个 PointFinal虚继承基类的偏移量
    24 到内存分布中第二个 PointFinal虚继承基类的偏移量
    40 到内存分布中第三个 PointFinal虚继承基类的偏移量

    Point22(vbptr)
    Point22的虚表中存着它所有虚父类的偏移量
    0
    -24Point0 的偏移量
    -16Point1 的偏移量
三个基类继承下无虚继承下的情况:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Datainfo 
{
	int** _ptr;
	string _dataInfo;
	void PrintSelf()
	{
		cout << _dataInfo;
		while (_dataInfo.size()<40)
		{
			_dataInfo.append(" ");
			cout << ' ';
		}
		cout << _ptr<< endl;
	}

};
bool GreaterSort(Datainfo& Left,Datainfo& Right)
{
	return Left._ptr < Right._ptr;
}

std::vector<Datainfo> StructDataInfo;

typedef void(*FUNC)();

void PrintVTable(int** &VTable)
{
	
	std::cout << " 虚表函数地址: "<<VTable << std::endl;
	for (int i = 0; (VTable[i]) != NULL; ++i)
	{
		__try
		{


			FUNC f = (FUNC)VTable[i];
			f();


			printf("<-第%d个虚函数地址: 0X%x,\n", i, VTable[i]);
		}
		__except (1)
		{
			std::cout << " 虚表函数结束 " << std::endl;
			break;
		}


	}
	std::cout << std::endl;

}
class Interface_PointC
{
public:
	void PrintInterface_PointC()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointC _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _a is :";
		NewData._ptr =(int**) &this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _c is :";
		NewData._ptr = (int**)&this->_c;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
			
	}
	void PrintVPtrTableC()
	{
		std::cout << "Interface_PointC的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
	int _a = 0;
	int _b = 0;
	int _c = 0;
	int _BaseData = 0;
	virtual void BaseFunction() {
		std::cout << "Interface_PointA:: BaseFunction ";
	};
private:
	virtual void Interface_PointC_1() {
		std::cout << " Interface_PointC::Interface_PointC_1 ";
	}
	virtual void Interface_PointC_2() {
		std::cout << " Interface_PointC::Interface_PointC_2 ";
	}
	virtual void BaseFunctionA() {
		std::cout << "Interface_PointC:: BaseFunctionA ";
	};
	virtual void BaseFunctionB() {
		std::cout << "Interface_PointC:: BaseFunctionB ";
	};

};
void PrintAllData()
{
	std::cout << "输出所有" << endl;

	std::sort(StructDataInfo.begin(), StructDataInfo.end(), GreaterSort);

	for  (auto var : StructDataInfo)
	{
		var.PrintSelf();
	}	
}
class Interface_PointA:virtual public Interface_PointC
{
public:
	void PrintInterface_PointA()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointA Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
	}

	int _a = 0;

	void PrintVPtrTableA()
	{
		std::cout << "Interface_PointA的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}

private:

	virtual void Interface_PointA_1() {
		std::cout << " Interface_PointA::Interface_PointA_1 ";
	}

	virtual void Interface_PointA_2() {
		std::cout << "Interface_PointA:: Interface_PointA_2 ";
	}

	virtual void BaseFunction() {
		std::cout << "Interface_PointA:: BaseFunction ";
	};

	virtual void BaseFunctionA() {
		std::cout << "Interface_PointA:: BaseFunctionA ";
	};

	
};
class Interface_PointB :virtual public Interface_PointC
{
public:
	int _b = 0;

	void PrintInterface_PointB()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointB Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
	}
	void PrintVPtrTableB()
	{
		std::cout << "Interface_PointB的虚表" << std::endl;
		int** pVptrThird = (int**)(this) ;
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:
	virtual void Interface_PointB_1() {
		std::cout << " Interface_PointB::Interface_PointB_1 ";
	}

	virtual void Interface_PointB_2() {
		std::cout << " Interface_PointB::Interface_PointB_2 ";
	}

	virtual void BaseFunction() {
		std::cout << "Interface_PointB:: BaseFunction ";
	};

	virtual void BaseFunctionB() {
		std::cout << "Interface_PointB:: BaseFunctionB ";
	};

};
//
class Point3D :public Interface_PointA,public Interface_PointB
{
public:
	void PrintPoint3D()
	{
		Datainfo NewData;
		NewData._dataInfo = "Point3D Start  this is:";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_c is :";
		NewData._ptr = (int**)&this->_c;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_Point3Data is :";
		NewData._ptr = (int**)&this->_Point3Data;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
		PrintInterface_PointA();
		PrintInterface_PointB();
		PrintInterface_PointC();
	}

	void PrintVPtrTablePoint3D()
	{
		std::cout << "Point3D的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}

	virtual void Interface_PointB_1() {
		std::cout << " Point3D::Interface_PointB_1 ";
	}

	virtual void Interface_PointA_1() {
		std::cout << " Point3D::Interface_PointA_1 ";
	}

	void PrintVPtrTable()
	{
		PrintVPtrTableC();
		PrintVPtrTableB();
		PrintVPtrTableA();
		PrintVPtrTablePoint3D();
	}

	virtual void Point3D_1() {
		std::cout << " Point3D::Point3D_1 ";
	}

	virtual void Point3D_2() {
		std::cout << "Point3D:: Point3D_2 ";
	}

	int _a = 0;
	int _b = 0;
	int _c = 0;
	int _Point3Data = 0;

	virtual void BaseFunction() override {
		std::cout << " Point3D::BaseFunction ";
	};

};


int main()
{

	Point3D TestChildInstance = Point3D();

	TestChildInstance.PrintPoint3D();

	std::cout << "sizeof(void*) is                 " << sizeof(void*) << std::endl;
	std::cout << "sizeof(int) is                   " << sizeof(int) << std::endl;
	std::cout << "sizeof(Point3D) is               " << sizeof(Point3D) << std::endl;

	PrintAllData();
	TestChildInstance.PrintVPtrTable();
	
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三个基类单虚继承且承菱形继承关系的情况:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Datainfo 
{
	int** _ptr;
	string _dataInfo;
	void PrintSelf()
	{
		cout << _dataInfo;
		while (_dataInfo.size()<40)
		{
			_dataInfo.append(" ");
			cout << ' ';
		}
		cout << _ptr<< endl;
	}

};
bool GreaterSort(Datainfo& Left,Datainfo& Right)
{
	return Left._ptr < Right._ptr;
}

std::vector<Datainfo> StructDataInfo;

typedef void(*FUNC)();

void PrintVTable(int** &VTable)
{
	
	std::cout << " 虚表函数地址: "<<VTable << std::endl;
	for (int i = 0; (VTable[i]) != NULL; ++i)
	{
		__try
		{


			FUNC f = (FUNC)VTable[i];
			f();


			printf("<-第%d个虚函数地址: 0X%x,\n", i, VTable[i]);
		}
		__except (1)
		{
			std::cout << " 虚表函数结束 " << std::endl;
			break;
		}


	}
	std::cout << std::endl;

}
class Interface_PointC
{
public:
	void PrintInterface_PointC()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointC _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _a is :";
		NewData._ptr =(int**) &this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _c is :";
		NewData._ptr = (int**)&this->_c;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
			
	}
	void PrintVPtrTableC()
	{
		std::cout << "Interface_PointC的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
	int _a = 0;
	int _b = 0;
	int _c = 0;
	int _BaseData = 0;
	virtual void BaseFunction() {
		std::cout << "Interface_PointA:: BaseFunction ";
	};
private:
	virtual void Interface_PointC_1() {
		std::cout << " Interface_PointC::Interface_PointC_1 ";
	}
	virtual void Interface_PointC_2() {
		std::cout << " Interface_PointC::Interface_PointC_2 ";
	}
	virtual void BaseFunctionA() {
		std::cout << "Interface_PointC:: BaseFunctionA ";
	};
	virtual void BaseFunctionB() {
		std::cout << "Interface_PointC:: BaseFunctionB ";
	};

};
void PrintAllData()
{
	std::cout << "输出所有" << endl;

	std::sort(StructDataInfo.begin(), StructDataInfo.end(), GreaterSort);

	for  (auto var : StructDataInfo)
	{
		var.PrintSelf();
	}	
}
class Interface_PointA:virtual public Interface_PointC
{
public:
	void PrintInterface_PointA()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointA Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
	}

	int _a = 0;

	void PrintVPtrTableA()
	{
		std::cout << "Interface_PointA的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}

private:

	virtual void Interface_PointA_1() {
		std::cout << " Interface_PointA::Interface_PointA_1 ";
	}

	virtual void Interface_PointA_2() {
		std::cout << "Interface_PointA:: Interface_PointA_2 ";
	}

	virtual void BaseFunction() {
		std::cout << "Interface_PointA:: BaseFunction ";
	};

	virtual void BaseFunctionA() {
		std::cout << "Interface_PointA:: BaseFunctionA ";
	};

	
};
class Interface_PointB :virtual public Interface_PointC
{
public:
	int _b = 0;

	void PrintInterface_PointB()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointB Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
	}
	void PrintVPtrTableB()
	{
		std::cout << "Interface_PointB的虚表" << std::endl;
		int** pVptrThird = (int**)(this) ;
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:
	virtual void Interface_PointB_1() {
		std::cout << " Interface_PointB::Interface_PointB_1 ";
	}

	virtual void Interface_PointB_2() {
		std::cout << " Interface_PointB::Interface_PointB_2 ";
	}

	virtual void BaseFunction() {
		std::cout << "Interface_PointB:: BaseFunction ";
	};

	virtual void BaseFunctionB() {
		std::cout << "Interface_PointB:: BaseFunctionB ";
	};

};
//
class Point3D :virtual public Interface_PointA,public Interface_PointB
{
public:
	void PrintPoint3D()
	{
		Datainfo NewData;
		NewData._dataInfo = "Point3D Start  this is:";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_c is :";
		NewData._ptr = (int**)&this->_c;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_Point3Data is :";
		NewData._ptr = (int**)&this->_Point3Data;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
		PrintInterface_PointA();
		PrintInterface_PointB();
		PrintInterface_PointC();
	}

	void PrintVPtrTablePoint3D()
	{
		std::cout << "Point3D的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}

	virtual void Interface_PointB_1() {
		std::cout << " Point3D::Interface_PointB_1 ";
	}

	virtual void Interface_PointA_1() {
		std::cout << " Point3D::Interface_PointA_1 ";
	}

	void PrintVPtrTable()
	{
		PrintVPtrTableC();
		PrintVPtrTableB();
		PrintVPtrTableA();
		PrintVPtrTablePoint3D();
	}

	virtual void Point3D_1() {
		std::cout << " Point3D::Point3D_1 ";
	}

	virtual void Point3D_2() {
		std::cout << "Point3D:: Point3D_2 ";
	}

	int _a = 0;
	int _b = 0;
	int _c = 0;
	int _Point3Data = 0;

	virtual void BaseFunction() override {
		std::cout << " Point3D::BaseFunction ";
	};

};




int main()
{

	Point3D TestChildInstance = Point3D();

	TestChildInstance.PrintPoint3D();

	std::cout << "sizeof(void*) is                 " << sizeof(void*) << std::endl;
	std::cout << "sizeof(int) is                   " << sizeof(int) << std::endl;
	std::cout << "sizeof(Point3D) is               " << sizeof(Point3D) << std::endl;

	PrintAllData();
	TestChildInstance.PrintVPtrTable();
	
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三个基类全虚继承且承菱形继承关系的情况:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct Datainfo 
{
	int** _ptr;
	string _dataInfo;
	void PrintSelf()
	{
		cout << _dataInfo;
		while (_dataInfo.size()<40)
		{
			_dataInfo.append(" ");
			cout << ' ';
		}
		cout << _ptr<< endl;
	}

};
bool GreaterSort(Datainfo& Left,Datainfo& Right)
{
	return Left._ptr < Right._ptr;
}
std::vector<Datainfo> StructDataInfo;
typedef void(*FUNC)();

void PrintVTable(int** &VTable)
{
	
	std::cout << " 虚表函数地址: "<<VTable << std::endl;
	for (int i = 0; (VTable[i]) != NULL; ++i)
	{
		__try
		{


			FUNC f = (FUNC)VTable[i];
			f();


			printf("<-第%d个虚函数地址: 0X%x,\n", i, VTable[i]);
		}
		__except (1)
		{
			std::cout << " 虚表函数结束 " << std::endl;
			break;
		}


	}
	std::cout << std::endl;

}
class Interface_PointC
{
public:
	void PrintInterface_PointC()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointC _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _a is :";
		NewData._ptr =(int**) &this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _c is :";
		NewData._ptr = (int**)&this->_c;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointC _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
			
	}
	void PrintVPtrTableC()
	{
		std::cout << "Interface_PointC的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
	int _a = 0;
	int _b = 0;
	int _c = 0;
	int _BaseData = 0;
	virtual void BaseFunction() {
		std::cout << "Interface_PointA:: BaseFunction ";
	};
private:
	virtual void Interface_PointC_1() {
		std::cout << " Interface_PointC::Interface_PointC_1 ";
	}
	virtual void Interface_PointC_2() {
		std::cout << " Interface_PointC::Interface_PointC_2 ";
	}
	virtual void BaseFunctionA() {
		std::cout << "Interface_PointC:: BaseFunctionA ";
	};
	virtual void BaseFunctionB() {
		std::cout << "Interface_PointC:: BaseFunctionB ";
	};

};
void PrintAllData()
{
	std::cout << "输出所有" << endl;
	std::sort(StructDataInfo.begin(), StructDataInfo.end(), GreaterSort);
	for  (auto var : StructDataInfo)
	{
		var.PrintSelf();
	}	
}
class Interface_PointA:virtual public Interface_PointC
{
public:
	void PrintInterface_PointA()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointA Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointA _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
	}
	int _a = 0;
	void PrintVPtrTableA()
	{
		std::cout << "Interface_PointA的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:
	virtual void Interface_PointA_1() {
		std::cout << " Interface_PointA::Interface_PointA_1 ";
	}
	virtual void Interface_PointA_2() {
		std::cout << "Interface_PointA:: Interface_PointA_2 ";
	}
	virtual void BaseFunction() {
		std::cout << "Interface_PointA:: BaseFunction ";
	};
	virtual void BaseFunctionA() {
		std::cout << "Interface_PointA:: BaseFunctionA ";
	};

	
};
class Interface_PointB :virtual public Interface_PointC
{
public:
	int _b = 0;
	void PrintInterface_PointB()
	{
		Datainfo NewData;
		NewData._dataInfo = "Interface_PointB Start  this is :";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Interface_PointB _BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
	}
	void PrintVPtrTableB()
	{
		std::cout << "Interface_PointB的虚表" << std::endl;
		int** pVptrThird = (int**)(this) ;
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
private:
	virtual void Interface_PointB_1() {
		std::cout << " Interface_PointB::Interface_PointB_1 ";
	}
	virtual void Interface_PointB_2() {
		std::cout << " Interface_PointB::Interface_PointB_2 ";
	}
	virtual void BaseFunction() {
		std::cout << "Interface_PointB:: BaseFunction ";
	};
	virtual void BaseFunctionB() {
		std::cout << "Interface_PointB:: BaseFunctionB ";
	};

};
//
class Point3D :virtual public Interface_PointA,virtual public Interface_PointB
{
public:
	void PrintPoint3D()
	{
		Datainfo NewData;
		NewData._dataInfo = "Point3D Start  this is:";
		NewData._ptr = (int**)this;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_a is :";
		NewData._ptr = (int**)&this->_a;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_b is :";
		NewData._ptr = (int**)&this->_b;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_c is :";
		NewData._ptr = (int**)&this->_c;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_Point3Data is :";
		NewData._ptr = (int**)&this->_Point3Data;
		StructDataInfo.push_back(NewData);

		NewData._dataInfo = "Point3D Child  &_BaseData is :";
		NewData._ptr = (int**)&this->_BaseData;
		StructDataInfo.push_back(NewData);
		PrintInterface_PointA();
		PrintInterface_PointB();
		PrintInterface_PointC();
	}
	void PrintVPtrTablePoint3D()
	{
		std::cout << "Point3D的虚表" << std::endl;
		int** pVptrThird = (int**)(this);
		int** pVptrThirdResult = (int**)(pVptrThird[0]);
		PrintVTable(pVptrThirdResult);
	}
	virtual void Interface_PointB_1() {
		std::cout << " Point3D::Interface_PointB_1 ";
	}
	virtual void Interface_PointA_1() {
		std::cout << " Point3D::Interface_PointA_1 ";
	}
	void PrintVPtrTable()
	{
		PrintVPtrTableC();
		PrintVPtrTableB();
		PrintVPtrTableA();
		PrintVPtrTablePoint3D();
	}
	virtual void Point3D_1() {
		std::cout << " Point3D::Point3D_1 ";
	}
	virtual void Point3D_2() {
		std::cout << "Point3D:: Point3D_2 ";
	}
	int _a = 0;
	int _b = 0;
	int _c = 0;
	int _Point3Data = 0;
	virtual void BaseFunction() override {
		std::cout << " Point3D::BaseFunction ";
	};

};




int main()
{

	Point3D TestChildInstance = Point3D();
	//GetVPtrTableAddress(&TestChildInstance);
	TestChildInstance.PrintPoint3D();
	std::cout << "sizeof(void*) is                 " << sizeof(void*) << std::endl;
	std::cout << "sizeof(int) is                   " << sizeof(int) << std::endl;
	std::cout << "sizeof(Point3D) is               " << sizeof(Point3D) << std::endl;
	//std::cout << std::endl;
	PrintAllData();
	TestChildInstance.PrintVPtrTable();
	
	//
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

结语:

情况还是挺复杂,以上结论是根据结果反推验证而得,看到本文者可自行用本文提供例子进行反推。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值