函数覆盖有哪些用例?

  • 本文关键字:覆盖 函数 c++
  • 更新时间 :
  • 英文 :


我正在回顾一些 c++ 概念(几年前我用过它(,函数重载的概念现在对我来说很有意义,尤其是对于我去年在 powershell 编程经验中遇到的一些场景。 例如,现在我可以轻松地向某人解释它对于软件重构非常有用,使代码可读性更容易等......

我不明白的是函数覆盖的用法/好处。它有哪些好的用例?从研究中,我刚刚读到它用于为父类中的子类函数具有不同的行为,但是,您不能只将子类中的函数命名为其他名称,并直接以这种方式调用它而不用担心父类函数?

您不能只将子类中的函数命名为其他名称,然后直接以这种方式调用它而不用担心父类函数吗?

不,因为不可能有运行时动态调度,这是多态性的全部基础。

(动态调度是用C++(和大多数其他语言(使用基于vtable(virtual(的调用实现的(。其他语言如Objective-C和Smalltalk使用消息传递范式。用 C 语言编写的程序必须自己实现 vtable-call-call 或消息传递(例如通过使用函数指针(。

考虑这个伪代码[3]的例子:

class AnyCat {
abstract void MakeSound();
}
class HouseCat extends AnyCat {
override void MakeSound() {
Console.WriteLine( "Meow" );
}
}
class Lion extends AnyCat {
override void MakeSound() {
Console.WriteLine( "Roar" );
}
}

static void Main() {
AnyCat cat = GetRandomNumber() % 2 == 0 ? new HouseCat() : new Lion();
cat.MakeSound(); // <-- this is a vtable/virtual-call
}

由于cat运行时可以是HouseCat的,也可以是Lion的,所以编译器(以及程序员!(不能使用"静态调用"[4]来MakeSound


[3] 我没有使用 C++ 的class声明语法,因为它太冗长了,而且C++目前不需要使用override说明符,所以对于初学者来说,当方法声明会导致 vtable 调用或只是阴影时,它并不明显。

[4] 在这种情况下,"静态调用"在一般意义上意味着"静态编译"或"在编译时固定"(例如"静态类型"(。它与 OOP 编程语言中的static关键字或static-方法无关(尽管有趣的事实:对static方法的所有调用都是静态调用(。

如果子类中的函数需要与基类中提供的函数具有不同的功能,则可以重写该函数。一个例子(非常简洁,参见其他编程语言(:

struct Person
{
virtual ~Person() = default; // make this a polymorphic type
void bonus()
{
throw "Not a chance.";
}
};
struct Boss : Person
{
void bonus() // overrides the base class function
{
// open banking payment system
// pay the bonus
// close the banking payment system
}
};

这种经典的功能覆盖确实已经过时了,正在被组合型模式所取代。在这种情况下bonus()可以是Person中实现的纯虚函数,在每个子类中实现。

最新更新