广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++深度探索虚函数指针示例
  • 382
分享到

C++深度探索虚函数指针示例

C++虚函数C++虚函数指针 2022-12-19 15:12:30 382人浏览 薄情痞子
摘要

代码描述:定义一个Person类为基类,ChinesePer 类与EnglishPer类都继承于此基类。 class Person { public: void speak() {

代码描述:定义一个Person类为基类,ChinesePer 类与EnglishPer类都继承于此基类。

class Person
{
public:
	void speak() {
		cout << "说人话" << endl;
	}
private:
	int m_type = 1 ;
};
class ChinesePer :public Person {
public:
	void speak() {
		cout << "说中国话chinese..." << endl;
	}
};
class EnglishPer :public Person {
public:
	void speak() {
		cout << "说英国话english..." << endl;
	}
};

先看看此时各个类占用的内存信息:

int main() {
	int person_size = sizeof(Person);
	int Chineseper_size = sizeof(ChinesePer);
	int Englishper = sizeof(EnglishPer);
}

可以看到三个类的大小都为4个字节,占用的情况就是 类中的m_type变量。

将基类中的 speak() 函数加上virtual关键字 ,成为虚函数后再次查看内存字节大小:

可以看到多出了4个字节大小的空间(X86),三个类的大小都为 8。其实就是多出了一个指针的大小,4个字节 ,创建一个子类对象就可以明显看出来:

可以得出结论一:继承过来的成员变量 m_type(4个字节) + _vfptr(4个字节) = 8个字节。

继续探索虚函数表的原理, 创建以下子类对象并通过父类指针指向子类对象调用speak函数发生多态:

int main(){
	ChinesePer chs;
	ChinesePer chs2;
	EnglishPer eng;
    Person *ptr = &chs;		//父类指针指向子类对象
	Person *ptr1 = &chs2;
	Person *ptr2 = &eng;
	ptr->speak();
	ptr1->speak();
	ptr2->speak();
}

以上代码执行后会发生多态:

此时我们看看三个对象的内存分布:

用图片简要描述一下就是:

在这里可以先得到结论二: 同一个子类的所有对象共享一个虚函数表,指向虚函数表的指针_vptr是相同的。

在内存分布上查看一下 eng对象的虚函数指针地址情况:

可以看到该虚函数指针的地址上的值,存放的正是 该子类中的重写函数 speak()函数的地址。

如果把这个地址的值,修改为 Chineseper 类中的重写函数speak() 的地址值,会发生什么?

手动修改了eng对象中虚函数指针内的地址值,将改值本来是存放的是 EnglishPer 类中的speak() 函数的地址,现在更改为 ChinesePer 类中speak() 函数的地址。

单步走发生多态:

至此可以得出结论三:

当基类函数加了virtual 关键字后,虚函数的调用方法是间接调用:先查虚函数表的地址(也就是指向虚函数表的指针 _vptr),再查虚函数表中的虚函数指针。

不妨在基类继续添加两个虚函数

class Person
{
public:
	virtual void speak() {
		cout << "说人话" << endl;
	}
	virtual void eat() {
		cout << "吃饭" << endl;
	}
	virtual void sleep() {
		cout << "睡觉" << endl;
	}
private:
	int m_type =1 ;
};

子类只重写了speak函数,查看一下chs对象的虚函数指针地址存放的值:

的确存放的还是各个函数的地址,且是连续存放的,因此在进行查表调用虚函数的时候,也是每移动4个字节指向的就是一个函数的指针地址。

可以简要描述一下形式就很直观了:

总结

1.增加了virtual 关键字的对象头部4个字节是一个指针,指向了虚函数表的地址(单继承情况下)。

2.同一个子类的所有对象共享一个虚函数表,指向虚函数表的指针_vptr是相同的。

3.当基类函数加了virtual 关键字后,虚函数的调用方法是间接调用:先查虚函数表的地址(也就是指向虚函数表的指针 _vptr),再查虚函数表中的虚函数指针。

到此这篇关于c++深度探索虚函数指针示例的文章就介绍到这了,更多相关C++虚函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++深度探索虚函数指针示例

本文链接: https://www.lsjlt.com/news/175260.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++深度探索虚函数指针示例
    代码描述:定义一个Person类为基类,ChinesePer 类与EnglishPer类都继承于此基类。 class Person { public: void speak() {...
    99+
    2022-12-19
    C++虚函数 C++虚函数指针
  • C++深度探索虚函数覆盖示例
    代码描述:Person类为基类,且基类中定义了三个虚函数。ChinesePer 类为继承于改基类的子类,且子类没有进行虚函数重写 。 class Person { public: ...
    99+
    2022-12-19
    C++虚函数 C++虚函数覆盖
  • C/C++函数指针深入探究
    目录函数指针语法函数地址声明使用函数指针调用函数深入理解函数指针使用typedef 简化函数指针 为什么要使用函数指针? 调用的灵活性和通用性。 试想一下,我们在设计初期并不知道我们...
    99+
    2022-11-13
  • C++中返回指向函数的指针示例
    在C++中,函数的形参可以是指向函数的指针,函数也可以返回函数的指针。例如:int (*ff(int)) (int *,int);表示:ff(int)是一个函数,带有一个int型的形...
    99+
    2022-11-15
    指向函数的指针 C++
  • C语言中返回值指针函数的示例分析
    这篇文章主要为大家展示了“C语言中返回值指针函数的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言中返回值指针函数的示例分析”这篇文章吧。   #inc...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作