【C++】重载、重写、重定义的辨析

本文详细解释了C++中的重载、重写和重定义概念,比较了它们的区别,探讨了虚函数中不能使用static的原因,以及关于重写函数访问修饰符的规则。着重介绍了动态绑定在虚函数中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重载、重写、重定义对比

在这里插入图片描述

一、重载(overload)

指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断
(1)在同一个作用域中
(2)函数名字相同
(3)参数列表不同(参数个数,参数类型,类型顺序…)
(4)virtual 关键字可有可无
(5)返回值可以相同也可以不同

二、重写 / 覆盖(override)

指派生类中有一个跟基类(返回值类型(除了协变),函数名,参数列表)相同的虚函数,特征是:
(1)两个虚函数分别位于派生类与基类
(2)函数名字相同
(3)参数列表相同
(4)基类函数必须在函数前面加 virtual 关键字,不能有 static
(5)返回值相同(除了协变)
(6)重写函数的访问修饰符可以不同
(派生类中重写的函数可以放宽其在基类中的访问修饰符,尽管基类虚函数是 private 的,派生类中重写改写为 public,protected 也是可以的)

三、重定义 / 隐藏(redefining)

(1)两函数分别位于派生类与基类
(2)函数名字相同
(3)返回值可以不同
(4)参数列表不同。此时,不论有无 virtual 关键字,基类的函数将被隐藏(注意别跟重载混淆,首先作用域就不同,重载要求在同一作用域) 。
(5)参数相同,但是基类函数没有 virtual关键字。此时,基类的函数被隐藏。
(6)隐藏的函数不具备多态性。
两个同名函数分别位于派生类与基类,不是构成重写就是构成重定义

* 为什么在虚函数中不能使用 static 关键字?

为什么在虚函数中不能使用 static 关键字呢?
这需要考虑两者的特性——

在C++中,虚函数和静态成员函数有不同的语义和用途,因此它们在语法上是互斥的。

动态绑定(Dynamic Binding)

虚函数的一个关键特性是动态绑定(也称为运行时多态性)。当通过基类的指针或引用调用虚函数时,实际调用的是派生类的版本,这个决定是在运行时根据对象的实际类型进行的——这种机制使得程序能够根据对象的实际类型执行我们希望的操作。

静态成员函数

静态成员函数属于类而不是类的实例。
静态成员函数在整个类中是共享的。
静态成员函数在编译时就被解析,因为它们不依赖于对象的实际类型。

conclusion

由于虚函数和静态成员函数具有不同的调用和解析机制,将它们结合在一起可能导致混淆。

在C++中,虚函数是通过虚函数表和虚指针来实现的,而静态成员函数不涉及这些机制~

因此,为了保持语言的一致性和清晰性,C++规定在虚函数声明中不能使用 static 关键字。在使用虚函数时,编译器会使用动态绑定机制,而静态成员函数不参与这种机制,因此在虚函数中使用 static 不合适

* 重写函数的访问修饰符可以不同吗?

派生类中重写基类中的虚函数时,派生类中的函数的访问修饰符可以有一些变化,但有一些限制:

缩小访问权限

派生类中重写的函数可以缩小其在基类中的访问修饰符。

  1. 如果基类中的虚函数是 public,那么在派生类中可以选择将其重写为 public、protected 或 private。
  2. 如果基类中的虚函数是 protected,那么在派生类中可以选择将其重写为 protected 或 private。
  3. 如果基类中的虚函数是 private,则不能在派生类中直接重写。
    在这里插入图片描述

放宽访问权限

派生类中重写的函数不可以放宽其在基类中的访问修饰符。

例如,如果基类中的虚函数是private,则派生类中重写时不能将其放宽为public。

在这里插入图片描述在这里插入图片描述

评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐徐同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值