C++ :---虚表与虚函数

举报
月照银海似蛟龙 发表于 2022/08/12 08:57:23 2022/08/12
【摘要】 虚表 类中虚函数如果类中存在虚函数,无论存在多少虚函数,都只有一个vfptr虚指针,vfptr指向一个vftable虚表,vftable存放的是本类中虚函数的入口地址。virtual 关键字的函数是虚函数,虚函数中存在虚指针,虚指针指向虚表,虚表存放虚函数的入口地址 类模型示例图#include<iostream>using namespace std;class A{public: vi...

虚表

类中虚函数

如果类中存在虚函数,无论存在多少虚函数,都只有一个vfptr虚指针,vfptr指向一个vftable虚表,vftable存放的是本类中虚函数的入口地址。
在这里插入图片描述
在这里插入图片描述
virtual 关键字的函数是虚函数,虚函数中存在虚指针,虚指针指向虚表,虚表存放虚函数的入口地址

类模型示例图

#include<iostream>
using namespace std;

class A
{
public:
	virtual void fa() { cout << "A:fa" << endl; }
	virtual void ga() { cout << "A:ga" << endl; }
	virtual void ha() { cout << "A:ha" << endl; }
	void ff() { cout << "A:FF" << endl; }
private:
	int m_i;
};
class B
{
};
int main()
{
	cout << sizeof(A) << endl;
	A a;
	return 0;
}

代码图解
在这里插入图片描述

代码示例

取指针A类中的fa函数

在这里插入图片描述
用指针取出函数

#include<iostream>
using namespace std;

class A
{
public:
	virtual void fa() { cout << "A:fa" << endl; }
	virtual void ga() { cout << "A:ga" << endl; }
	virtual void ha() { cout << "A:ha" << endl; }
};
class B :public A
{
	virtual void fb() { cout << "B:fb" << endl; }
	virtual void gb() { cout << "B:gb" << endl; }
};
int main()
{
	cout << sizeof(B) << endl;
	B b;
	typedef void (*Fun)();
	Fun pf = (Fun) * ((int*)*(int*)(&b));
	pf();//A:fa();

	pf = (Fun) * ((int*)*(int*)(&b) + 1);
	pf();//A:ga();

	pf = (Fun) * ((int*)*(int*)(&b) + 2);
	pf();//A:ha();

	pf = (Fun) * ((int*)*(int*)(&b) + 3);
	pf();//B:fb();

	pf = (Fun) * ((int*)*(int*)(&b) + 4);
	pf();//B:gb();

	return 0;
}

代码图解
在这里插入图片描述
运行结果
在这里插入图片描述
数组下标为什么从0开始?
数组下标表示当前元素距离首地址的偏移量。

面试例题

求此程序运行结果?
代码示例

#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
	char a[5] = { 1,1,1,1,1 };

	int* p = (int*)(a);

	printf("%d\n", *p);
	return 0;
}

运行结果
在这里插入图片描述
代码图解
在这里插入图片描述

单继承

代码示例(覆盖)

class A
{
public:
	virtual void fa() { cout << "A::fa" << endl; }
	virtual void ga() { cout << "A::ga" << endl; }
	virtual void ha() { cout << "A::ha" << endl; }
};
class B :public A
{
public:
	virtual void fa() { cout << "B::fa" << endl; }
	virtual void ga() { cout << "B::hb" << endl; }
};
int main()
{
	cout << sizeof(B) << endl;
	B b;
	return 0;
}

代码图解
在这里插入图片描述

多继承

代码示例

#include<iostream>
using namespace std;

class A
{
public:
	virtual void fa() { cout << "A::fa" << endl; }
	virtual void ga() { cout << "A::ga" << endl; }
};
class B
{
public:
	virtual void fb() { cout << "B::fb" << endl; }
	virtual void gb() { cout << "B::gb" << endl; }
};
class C
{
public:
	virtual void fc() { cout << "C::fc" << endl; }
	virtual void gc() { cout << "C::gc" << endl; }
};
class D :public A, public B, public C
{
public:
	virtual void fd() { cout << "D::fd" << endl; }
	virtual void gd() { cout << "D::gd" << endl; }
};
int main()
{
	cout << sizeof(D) << endl;//12字节,3个虚表指针
	D d;
	return 0;
}

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。