C++类之虚函数表及其内存布局(一个子类继承一个父类)

代码如下:

cpp 复制代码
#include<iostream>
class Base
{
public:
	Base(int i) :baseI(i) {};
	int getI() { return baseI; }
	static void countI() {};
	virtual void print(void) { std::cout << "Base::print()"; }
	virtual void printFun(void) { std::cout << "Base::printFun()"; }
	virtual ~Base() {}

private:
	int baseI;
	static int baseS;
};

class Derive : public Base
{
public:
	Derive(int d) :Base(1000), DeriveI(d) {};
	//overwrite父类虚函数
	virtual void printFun(void) { std::cout << "Drive::printFun()"; }
	// Derive声明的新的虚函数
	virtual void printBeforeDestructor() { std::cout << "Drive::printBeforeDestructor()"; }
	virtual ~Derive() {}
	virtual void printAfterDestructor() { std::cout << "Drive::printAfterDestructor()"; }
private:
	int DeriveI;
};


typedef void(*Fun)(void);

int main()
{
	Derive d(2000);
	//[0]
	std::cout << "[0]Base::vptr";
	std::cout << "\t地址:" << (int *)(&d) << std::endl;
	//vprt[0]
	std::cout << "  [0]";
	Fun fun0 = (Fun)*((int *)*((int *)(&d)));
	fun0();
	std::cout << "\t地址:\t" << *((int *)*((int *)(&d))) << std::endl;

	//vprt[1]
	std::cout << "  [1]";
	Fun fun1 = (Fun)*((int *)*((int *)(&d)) + 1);
	fun1();
	std::cout << "\t地址:\t" << *((int *)*((int *)(&d)) + 1) << std::endl;

	//vprt[2]析构函数无法通过地址调用,故手动输出
	std::cout << "  [2]" << "Derive::~Derive()" << std::endl;

	//vprt[3]
	std::cout << "  [3]";
	Fun fun3 = (Fun)*((int *)*((int *)(&d)) + 3);
	fun3();
	std::cout << "\t地址:\t" << *((int *)*((int *)(&d)) + 3) << std::endl;
	//vprt[4]
	std::cout << "  [4]";
	Fun fun4 = (Fun)*((int *)*((int *)(&d)) + 4);
	fun4();
	std::cout << "\t地址:\t" << *((int *)*((int *)(&d)) + 4) << std::endl;
	//[1]
	std::cout << "[1]Base::baseI=" << *(int*)((int *)(&d) + 1);
	std::cout << "\t地址:" << (int *)(&d) + 1;
	std::cout << std::endl;
	//[2]
	std::cout << "[2]Derive::DeriveI=" << *(int*)((int *)(&d) + 2);
	std::cout << "\t地址:" << (int *)(&d) + 2;
	std::cout << std::endl;
	return 0;
}

验证结果如下:

参考文章
图说C++对象模型:对象内存布局详解

相关推荐
不正经学生37 分钟前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
门思科技1 小时前
LoRaWAN 设备类别:Class A、B、C 对比与选型指南
c语言·开发语言·php
恋恋西风3 小时前
C++ 理解 std::thread 在单核和多核上的行为差异
开发语言·c++
Brilliantwxx3 小时前
【Linux】 进程(9)程序与进程地址空间(基础+进阶+面试题)
linux·运维·服务器·开发语言·c++
BizzZ_4 小时前
C++(22)——类型转换和IO流
开发语言·c++
小范同学_4 小时前
JDK1.7 与 JDK1.8 HashMap 底层原理对比 + 数组并发扩容死循环详解
java·开发语言
geovindu5 小时前
CSharp: 万年历
开发语言·后端·c#·.net
我找到地球的支点啦5 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
予昊5 小时前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
weixin_461408586 小时前
Mybatis-flex小记
java·开发语言·mybatis