多态 多继承的虚表深度剖析 (3)

这篇具有很好参考价值的文章主要介绍了多态 多继承的虚表深度剖析 (3)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

💯 博客内容:多态

😀 作  者:陈大大陈

🚀 个人简介:一个正在努力学技术的准C++后端工程师,专注基础和实战分享 ,欢迎私信!

💖 欢迎大家:这里是CSDN,我总结知识和写笔记的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

目录

普通菱形继承 

虚表指针偏移 

菱形虚继承的情况


普通菱形继承 

class Base1 {
public:
	virtual void func1() { cout << "Base1::func1" << endl; }
	virtual void func2() { cout << "Base1::func2" << endl; }
private:
	int b1;
};

class Base2 {
public:
	virtual void func1() { cout << "Base2::func1" << endl; }
	virtual void func2() { cout << "Base2::func2" << endl; }
private:
	int b2;
};

class Derive : public Base1, public Base2 {
public:
	virtual void func1() 
	{ 
		cout << "Derive::func1" << endl;
	}

	virtual void func3() { cout << "Derive::func3" << endl; }
private:
	int d1;
};

int main()
{
	Derive d;
	return 0;
}

上面这种多继承的情况,Derive有几个虚表呢?

多态 多继承的虚表深度剖析 (3),C语言初阶以及进阶内容专栏,c++,算法,开发语言,c语言,数据结构

答案是,因为继承了Base1和Base2两个类,所以有两个虚表。 

但是这样的话,就会衍生出一个问题,它自己的虚函数也就是func3放在哪里呢?

我没看到,编译器仍旧是故技重施,欺骗我们的眼睛,我们检测监测不到func3。 

我们打印一下第一张虚表,这很容易想到。

class Base1 {
public:
	virtual void func1() { cout << "Base1::func1" << endl; }
	virtual void func2() { cout << "Base1::func2" << endl; }
private:
	int b1;
};

class Base2 {
public:
	virtual void func1() { cout << "Base2::func1" << endl; }
	virtual void func2() { cout << "Base2::func2" << endl; }
private:
	int b2;
};

class Derive : public Base1, public Base2 {
public:
	virtual void func1() 
	{ 
		cout << "Derive::func1" << endl;
	}

	virtual void func3() { cout << "Derive::func3" << endl; }
private:
	int d1;
};

int main()
{
	Derive d;
	//打印第一张虚表
	PrintVFT((VFUNC*)(*(int*)&d));
	return 0;
}

多态 多继承的虚表深度剖析 (3),C语言初阶以及进阶内容专栏,c++,算法,开发语言,c语言,数据结构

虚表指针偏移 

那么,怎么打印第二张虚表呢? 

PrintVFT((VFUNC*)(*(int*)((char*)&d+sizeof(Base1))));

这么打印,需要注意的是,d是一个Derive类,加一的话会加上一个Derive的大小。

所以这里必须把它强制类型转换成char*。

其实也可以这么打印。

PrintVFT((VFUNC*)(*(int*)((Base1*)&d+1)));

多态 多继承的虚表深度剖析 (3),C语言初阶以及进阶内容专栏,c++,算法,开发语言,c语言,数据结构

结果是一样的。 

还可以这样写,最聪明的一种写法。

	Base2* ptr = &d;
	PrintVFT((VFUNC*)(*(int*)ptr));

Base2指针会自己切割,便宜到Base2那里。

我们得到结论,func3放到了第一个虚表里面。

菱形虚继承的情况

class A
{
public:
	virtual void func1() 
	{ 
		cout << "A::func1" << endl;
	}
public:
	int _a;
};


class B : public A
{
public:
	virtual void func1()
	{
		cout << "B::func1" << endl;
	}

	virtual void func3()
	{
		cout << "B::func3" << endl;
	}

public:
	int _b;
};


class C : public A
{
public:
	virtual void func1()
	{
		cout << "C::func1" << endl;
	}

	virtual void func5()
	{
		cout << "C::func5" << endl;
	}
public:
	int _c;
};

class D : public B, public C
{
public:
	virtual void func1()
	{
		cout << "D::func1" << endl;
	}

	virtual void func2()
	{
		cout << "D::func2" << endl;
	}
public:
	int _d = 1;
};

int main()
{
	D d;

	return 0;
}

先来看一个问题,D里有几张虚表?

答案是两张,这种情况就跟普通的多继承没两样。

多态 多继承的虚表深度剖析 (3),C语言初阶以及进阶内容专栏,c++,算法,开发语言,c语言,数据结构

改成虚拟菱形继承就不一样了。

多态 多继承的虚表深度剖析 (3),C语言初阶以及进阶内容专栏,c++,算法,开发语言,c语言,数据结构 此时有看起来有3个虚表,其实还是2个。菱形这块太复杂,我不分析了。文章来源地址https://www.toymoban.com/news/detail-744017.html

到了这里,关于多态 多继承的虚表深度剖析 (3)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++——多态与虚表

    目录 1.多态的实现 2.虚表 2.1虚函数重写是怎么实现的 2.2多态的原理 2.3静态绑定与动态绑定 3.单继承体系中的虚函数表 ​编辑4.多继承体系中的虚函数表 5.菱形继承的虚函数表 6.菱形虚拟继承的虚函数表 在C++中,要想实现多态,必须满足以下几个条件: 有继承关系 有虚函数

    2024年02月07日
    浏览(39)
  • 多态 虚函数表深度剖析 纯干货讲解(2)

    💯 博客内容:多态 😀 作  者:陈大大陈 🚀 个人简介:一个正在努力学技术的准C++后端工程师,专注基础和实战分享 ,欢迎私信! 💖 欢迎大家:这里是CSDN,我总结知识和写笔记的地方,喜欢的话请三连,有问题请私信 😘 😘 😘 目录 虚函数存在哪里?  虚函数的地

    2024年02月05日
    浏览(40)
  • 简单明了证明多态虚表是位于常量区

    证实虚表存储与常量区

    2024年02月16日
    浏览(39)
  • C++中的多态是什么?如何实现多态?解释一下C++中的虚函数和纯虚函数,它们的作用是什么?

    C++中的多态是什么?如何实现多态? 在C++中,多态(Polymorphism)是面向对象编程的三大特性之一,另外两个是封装(Encapsulation)和继承(Inheritance)。多态指的是允许一个接口(或一个父类引用)在多种数据类型上被实现,或者一个接口被多个不同的类以不同的方式实现。

    2024年02月19日
    浏览(60)
  • c、c++、java、python、js对比【面向对象、过程;解释、编译语言;封装、继承、多态】

    目录 内存管理、适用 区别 C 手动内存管理:C语言没有内置的安全检查机制,容易出现内存泄漏、缓冲区溢出等安全问题。 适用于系统级编程 C++ 手动内存管理:C++需要程序员手动管理内存,包括分配和释放内存,这可能导致内存泄漏和指针错误。 适用于游戏引擎和系统级编

    2024年02月08日
    浏览(76)
  • 【C语言】编译和链接深度剖析

    本小节,我们学习翻译环境和运行环境,其中我们将学习编译环境的4个阶段:预编译,编译(词法分析,语法分析,语义分析),汇编,链接,文章干货满满!学习起来吧😃! 在 ANSI C 的任何⼀种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换

    2024年01月20日
    浏览(62)
  • C语言内存模型的深度剖析

    在计算机体系结构中,内存被抽象为一个线性的地址空间,C语言内存模型即建立在此基础之上。每个存储单元都有一个唯一的地址,这个地址空间从0开始递增,范围受限于处理器架构和操作系统提供的物理或虚拟内存大小。 在C语言中,所有对象(包括变量、数组、结构体等

    2024年02月22日
    浏览(40)
  • 【C++进阶(二)】STL大法--vector的深度剖析以及模拟实现

    💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C++从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习C++   🔝🔝 和string的学习不同 vector即要掌握它的用法 更要会自己去实现一个vector 本章重点: 熟悉STL库中vector的接口函数 自己实现一个简易vector类 本

    2024年02月11日
    浏览(39)
  • 【C语言深度剖析——第三节(关键字3)】《C语言深度解剖》+蛋哥分析+个人理解

    本文由@睡觉待开机原创,未经允许不得转载。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言,共同进步! 前言: 本期我们继续探讨关于C深度解剖这本书相关内容,继上一篇博客,本篇博客来围绕“数据类型”、“原反补”有关话题进行探

    2024年01月21日
    浏览(43)
  • 【C语言深度剖析——第四节(关键字4)】《C语言深度解剖》+蛋哥分析+个人理解

    追求本质,不断进步 本文由@睡觉待开机原创,转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言,共同进步! 前言: 本节博客继续前篇内容进行续写,我们着重探求有符号与无符号数的问题,探求 整形在内存中的存储 这一课

    2024年01月20日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包