首页 > 其他分享 >虚函数,虚函数表,虚表指针,覆盖

虚函数,虚函数表,虚表指针,覆盖

时间:2024-09-27 11:51:49浏览次数:3  
标签:虚表 函数 子类 void 父类 指针

1、虚函数

在成员函数前面加virtual后,该函数就称为虚函数,此时该类就会像虚继承一样多了一个虚表指针(虚函数表指针、虚指针)

2、虚函数表

虚表指针指向的是属于该类的一张表格的首地址,该表格中记录了该类的所有虚函数的首地址

        如果类中没有其他成员变量

        通过((void(*)(void))(*(int*)*(int*)b))(); 可以直接通过虚函数表以及虚表指针来访问虚函数表中第一个虚函数void func(void)

#include <iostream>
using namespace std;

class Base
{
public:
	virtual void func(void)
	{
		cout << "Base func" <<endl;
	}
	virtual void func1(void)
	{
		cout << "Base func1" <<endl;
	}	
};

int main(int argc,const char* argv[])
{
	cout << sizeof(Base)<<endl;	
	Base* b = new Base;
	((void(*)(void))(*(int*)*(int*)b))();
}

3、覆盖

当使用virtual来修饰父类的成员函数时,此时父类中就会多一个虚表指针以及一张虚函数表,子类继承父类时,会把父类的虚表指针以及虚函数表一起继承过来,然后编译器回去比较父子类中同名的虚成员函数的格式,如果格式完全相同的虚函数,就会把子类中虚函数表中原来同名父类虚函数的地址改为子类同名函数的地址,此时就称为覆盖

此时使用父类指针或引用指向子类对象时,调用虚函数则会去执行被覆盖后的虚函数表中所指向子类的同名且格式相同的成员函数,不再调用父类的同名虚函数

#include <iostream>
using namespace std;

class Base
{
public:
	virtual void func(void)
	{
		cout << "Base func" <<endl;
	}
	virtual void func1(void)
	{
		cout << "Base func1" <<endl;
	}	
};

class Son:public Base
{
public:
	void func(void)
	{
		cout<< "Son func" <<endl;
	}

};
int main(int argc,const char* argv[])
{
	cout << sizeof(Base)<<endl;	
	Base* s = new Son;
	s->func();
}

4、构成覆盖的条件

①、子类以public继承父类

②、父类中被覆盖的函数必须是virtual修饰的成员函数

③、子类中必须有与父类虚函数同名的成员函数,且该函数的返回值、参数列表、常属性都必须相同

④、返回值类型相同,或者子类同名成员函数的返回值类型可以向父类虚函数的返回值类型做隐式转换,且有继承关系。

#include <iostream>
using namespace std;

class Base
{
public:
	virtual Base* func(void)
	{
		cout << "Base func" <<endl;
	}
	virtual void func1(void)
	{
		cout << "Base func1" <<endl;
	}	
};

class Son:public Base
{
public:
	Son* func(void)
	{
		cout<< "Son func" <<endl;
	}

};
int main(int argc,const char* argv[])
{
	cout << sizeof(Base)<<endl;	
	Base* s = new Son;
	s->func();
}

标签:虚表,函数,子类,void,父类,指针
From: https://blog.csdn.net/xjl1849395627/article/details/142526188

相关文章

  • 【高中数学/函数/零点】已知函数f(x)=lnx-x-a有两个不同的零点,求实数a的取值范围?
    【问题】已知函数f(x)=lnx-x-a有两个不同的零点,求实数a的取值范围?【出处】《高中数学的解题思维策略》P31例2-12杨林军著【解答】f(x)=lnx-x-a的零点即lnx-x-a=0,移项得lnx=x+af(x)的零点即y=lnx与y=x+a的交点横坐标要找两曲线交点,先找两曲线切点是不二法门y=x+a的斜率为1y=lnx的......
  • OpenCV视频I/O(3)视频采集类VideoCapture之获取当前使用的视频捕获 API 后端的名称函数
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述getBackendName函数是OpenCV中VideoCapture类的一个方法,用于获取当前使用的视频捕获API后端的名称。这可以帮助开发者了解当前VideoCapture实例正在使用哪个后端来处理视......
  • OpenCV视频I/O(2)视频采集类VideoCapture之检索视频流的各种属性函数get()的使用
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述返回指定的VideoCapture属性。VideoCapture的get()函数用于检索视频流的各种属性。这个函数允许你查询视频源的状态和配置,例如分辨率、帧率等。函数原型virtualdoublec......
  • MySQL窗口函数汇总
    1.窗口函数概述窗口函数是一种SQL函数,非常适合于数据分析,其最大的特点就是:输入值是从SELECT语句的结果集中的一行或者多行的"窗口"中获取的,也可以理解为窗口有大有小(行数有多有少)。通过OVER子句,窗口函数与其他的SQL函数有所区别,如果函数具有OVER子句,则它是窗口函数。如果它缺少了O......
  • javascript 匿名函数之立即执行
    函数分为具名函数和匿名函数,具名函数需要先声明在进行调用,而匿名函数是完全没有值。例如:我们设置点击事件中的function就是匿名函数document.addEventListener('click',function(){})我们可以设置匿名函数立即执行。好处是一方面可以防止变量污染,另外一方面,......
  • 9.27 代码练习,以及教你写自己的qsort函数
    学生成绩系统代码include<stdio.h>typedefstructStudent{intnum;charname[50];intgrade[10];}stu;intcmp(intcount[],int*n){intmax=0;for(inti=0;i<*n;i++){if(count[i]>max){max=count[i];}}returnmax;}intmain(){int......
  • 信息安全工程师(19)HASH函数与数字签名
    一、Hash函数1、定义    Hash函数,又称散列函数或哈希函数,是一种将任意长度的输入(称为预映射或消息)通过散列算法变换成固定长度输出(称为散列值或哈希值)的函数。这种转换是单向的,即不能从哈希值反向推导出原始输入。2、特性单向性:难以根据哈希值反向求出原始数据。......
  • C标准库<string.h>-str、strn开头的函数
    char*strcat(char*dest,constchar*src)函数功能strcat函数用于将一个字符串追加到另一个字符串的尾部。参数解释dest:指向目标字符串的指针,这个字符串的尾部将被追加 src 字符串的内容。src:指向源字符串的指针,其内容将被追加到 dest 字符串的尾部。返回值返回......
  • C标准库<string.h>-mem开头的函数
    void*memchr(constvoid*str,intc,size_tn)函数功能在参数str所指向的内存区域的前n个字节中搜索第一次出现字符c(转换为无符号字符类型)的位置。参数解释str:指向要被搜索的内存区域的指针。c:要搜索的字符,以整数形式给出,但会被转换为无符号字符类型进行搜索。n:指定要搜......
  • C标准库<math.h> (幂函数、对数函数)
    幂函数doublepow(doublex,doubley)函数简介用于计算x的y次幂参数介绍x:底数,可以是正数、负数或零。y:指数,可以是整数或非整数。返回值函数返回计算结果,即x的y次幂。结果的类型是double。函数用法#include<stdio.h>#include<math.h>intmain(){......