当前位置: 首页 > article >正文

【C++】虚函数

一、什么是虚函数

在类的成员函数前加上virtual关键字,这个函数就是虚函数。

虚函数的所用就是完成多态。多态示例如下:

class A
{
	
public:
	virtual void func()//虚函数
	{
		cout << "A" << endl;
	}
	void ftwo()//普通函数
	{
		cout << "FA" << endl;
	}
private:
	int val=1;
};

class B :public A
{
public:
	void func()
	{
		cout << "B" << endl;
	}
	void Ftwo()
	{
		cout << "FB" << endl;
	}
private:
	int sum = 1;
};

int main()
{
	B b;
	A* pa =&b;//父类指针指向子类对象
	pa->ftwo();
	pa->func();
}

运行结果如下:

可以看到:父类指针调用函数,若该函数是虚函数,则调用子类的同名函数(无同名调用虚函数)。

                  如果不是虚函数,则正常调用父类的普通函数。

二、静态绑定与动态绑定

将一个名称与内存地址关联起来,就是绑定。

静态绑定:在编译时就完成函数的绑定(非虚函数)。

动态绑定:在运行时才完成函数的绑定(虚函数)。

虚函数要执行哪个版本在运行时才知道,所以是动态绑定。

三、虚函数的使用

3.1使用条件

1、使用环境必须是继承,在父类的成员函数前加virtual       

2、一定是指针或引用调用

3.2注意事项

1、虚函数必须有定义

2、构造函数不能是虚函数

3、函数被声明为虚函数后,所有子类该函数都是虚函数

3.3在子类中的使用

1、想使用虚函数完成多态,子类必须重写父类的虚函数

(重写/覆盖:返回值、函数名、参数列表、const属性必须与父类的虚函数相同。vritual可不加,但建议加上。参数的缺省值一定要相同,不然会有糟糕的后果)

2、当父类返回类型是父类指针/引用时,子类返回值可以为子类指针/引用

class A
{
	
public:
	virtual A* func()//返回类型为父类指针
	{
		cout << "A" << endl;
	}
private:
	int val=1;
};
class B :public A
{
public:
	virtual B* func()//返回类型为子类指针
	{
		cout << "B" << endl;
	}
private:
	int sum = 1;
};

int main()
{
	B b;
	A* pa =&b;
	pa->func();
}

3.4final和override说明符

1、final:在虚函数括号后面加,表示该函数无法被重写

2.override:在重写的函数括号后面加,检查重写是否正确(不加这个,重写写错检查不出来)

四、虚函数表、虚函数表指针

4.1虚表指针

编译器储存虚函数的方法是:给对象添加一个隐藏指针,该隐藏指针指向一个函数数组,这个数组被称为虚函数表,该隐藏指针被称为虚表指针(虚函数表指针),该指针存在类对象的最前面。

以下代码中,类里没有成员变量,但有隐藏的虚表指针,所以大小是8。

4.2虚函数表

父类定义虚函数后,父类对象会将虚函数的地址放到虚函数表中,自身存放一个虚表指针。

子类对象会独立的生成一个与父类相同的虚函数表,如果子类重写了父类的虚函数,那么在子类的虚函数表中会将父类的虚函数地址覆盖为自己的虚函数地址。


http://www.kler.cn/a/309209.html

相关文章:

  • PaaS云原生:分布式集群中如何构建自动化压测工具
  • 【韩老师零基础30天学会Java 】06章 数组、排序和查找
  • 一文了解 Tableau 2024.3 如何展现已发布数据源的数据模型
  • uniapp(API-Promise 化)
  • hive数据查询语法
  • 分段式爬虫和数据采集有什么关系
  • 多速率信号处理-CIC滤波器
  • Go第三方框架--gin框架(三)
  • SpringBoot 消息队列RabbitMQ死信交换机
  • 2025年最新大数据毕业设计选题-基于Spark分析相关
  • NC反弹shell
  • 微服务中间件之Nacos
  • Android 系统开发人员的权限说明文档
  • 解锁全球机遇:澳大利亚服务器租用市场的独特魅力
  • [C#学习笔记]Newtonsoft.Json
  • 中秋节特别游戏:给玉兔投喂月饼
  • MinIO - macOS上配置、Python调用
  • Delphi Web和Web服务开发目前有哪些选择
  • ASP.NET Core 中的 CRUD 操作
  • 游戏录屏不清楚怎么办?这些录屏技巧让画质飙升!
  • 标准的高防服务器是什么样的呢?
  • VSCode扩展连接虚拟机MySQL数据库
  • 【JavaScript】数据结构之堆
  • Python 数学建模——ARMA 时间序列分析
  • Unite Shanghai 2024 技术专场 | Unity 6及未来规划:Unity引擎和服务路线图
  • docker_持久化存储