关于C++多重继承下虚表结构的问题

 更新时间:2021年09月10日 10:37:49   作者:不会写代码的丝丽  
这篇文章主要介绍了C++ 多重继承下虚表结构的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

前言

昨天写一个项目时遇到一个很诡异的现象 如下代码所示:

class ParentA {
public :
	int a=0x123456;
	virtual void vFunParentA(){
		std::cout << "vFunParentA" << std::endl;
	}
};
class ParentB {
public:
	int b = 0x456;
	virtual void vFunParentB() {
		std::cout<<"vFunParentB"<<std::endl;
		int i = 0;
	}
};
class Child:public ParentA,public ParentB {
	int c = 0x789;
};
int main()
{

	//注意这里使用void*
	void* pChild = new Child;
	//强转
	ParentB* pParentB = (ParentB*)pChild;
	//强转
	ParentA* pParentA = (ParentA*)pChild;
	
	pParentB->vFunParentB();
	pParentA->vFunParentA();

	getchar();
	
}

现在执行后我们的预期输出为

vFunParentB
vFunParentA

但实际输出:

vFunParentA
vFunParentA

当时百思不得其“姐”,最后发现是自己对多重继承下的虚表内存结构不够了解。

博主另一外一篇关于虚表的:
c-15 c++虚表

在多重继承下Child内存结构应该是如下结构:

在这里插入图片描述

由于我们使用 void * 类型强转为ParentBParentA返回的指针地址依然是ParentA,而没有做内存偏移计算.如下图所示:

在这里插入图片描述

当我们不适用void*强转后编译器会帮我进行偏移计算会迫使ParentB偏移8字节,从而使pParentB 指向正确的内存虚表。

在这里插入图片描述

在单一继承下不会出现这类问题,我们最后看下本例中的内存结构:

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

到此这篇关于关于C++ 多重继承下虚表结构的问题的文章就介绍到这了,更多相关C++ 多重继承虚表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C/C++ Qt Tree与Tab组件实现分页菜单功能

    C/C++ Qt Tree与Tab组件实现分页菜单功能

    这篇文章主要介绍了C/C++ Qt Tree与Tab组件实现分页菜单功能,实现一个类似于树形菜单栏的功能,当用户点击菜单栏中的选项时则会跳转到不同的页面上,本文简单给大家分享实现代码,感兴趣的朋友跟随小编一起看看吧
    2021-11-11
  • 详解C/C++ Linux出错处理函数(strerror与perror)的使用

    详解C/C++ Linux出错处理函数(strerror与perror)的使用

    我们知道,系统函数调用不能保证每次都成功,必须进行出错处理,这样一方面可以保证程序逻辑正常,另一方面可以迅速得到故障信息。本文主要为大家介绍两个出错处理函数(strerror、perror)的使用,需要的可以参考一下
    2023-01-01
  • C 语言基础教程(我的C之旅开始了)[四]

    C 语言基础教程(我的C之旅开始了)[四]

    C 语言基础教程(我的C之旅开始了)[四]...
    2007-02-02
  • C语言单链表常见操作汇总

    C语言单链表常见操作汇总

    这篇文章主要介绍了C语言单链表常见操作,需要的朋友可以参考下
    2014-07-07
  • 浅析直接插入排序与折半插入排序

    浅析直接插入排序与折半插入排序

    这篇文章主要介绍了直接插入排序与折半插入排序,有需要的朋友可以参考一下
    2013-12-12
  • C++实现简易选课系统代码分享

    C++实现简易选课系统代码分享

    这篇文章主要介绍了C++实现简易选课系统及实现代码的分享,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你有所帮助
    2022-01-01
  • C语言实例讲解四大循环语句的使用

    C语言实例讲解四大循环语句的使用

    C语言有四大循环语句,他们之间可以进行任意转换。本文将首先对其语法进行讲解,然后通过一个实例用四种循环来实现。相信通过本文的学习,大家都能够对C语言循环语句有着熟练的掌握
    2022-05-05
  • C/C++实现获取硬盘序列号的示例代码

    C/C++实现获取硬盘序列号的示例代码

    获取硬盘的序列号、型号和固件版本号,此类功能通常用于做硬盘绑定或硬件验证操作,下面我们就来学习一下如何使用C/C++实现获取硬盘序列号吧
    2023-11-11
  • C++使用MIDI库实现演奏晴天

    C++使用MIDI库实现演奏晴天

    这篇文章主要为大家详细介绍了C++如何使用MIDI库实现演奏晴天歌曲,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解下
    2025-02-02
  • C语言实现页面置换 先进先出算法(FIFO)

    C语言实现页面置换 先进先出算法(FIFO)

    这篇文章主要为大家详细介绍了C语言实现页面置换,先进先出算法(FIFO),文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12

最新评论