C ++ - 继承中的重载与覆盖

C++ - Overloading vs Overriding in Inheritance

据我所知,覆盖是指当您有 2 个具有相同名称和函数 return 类型(voidintfloat 的函数时。 . 等)和相同的参数编号和类型。

并且重载是当您有 2 个具有相同名称但参数 number/types 或函数 return 类型应该不同的函数时。

但是今天当我在 class 时,我看到了这张幻灯片:

这不应该超载吗?不压倒一切?因为这里 return 类型发生了变化(从 void to float) 和 fa1() 函数在基础 class 中没有参数,但在派生的 class 中它有 float 参数。

如果这是压倒一切的,为什么?

ia1 没有超载。首先你不能重载变量。所以 ia1 绝对是一个覆盖。这也是一件危险的事情。在我的公司,我们的编码标准在任何情况下都不允许覆盖变量名。这只会导致混乱。

fa1 不过——这看起来像是过载。基本 class fa1() 不带参数,但 subclass 版本带浮点数。

在 C++ 中,派生 class 中的任何方法仅在它们的声明匹配时覆盖基 class 中的方法(我说“匹配”但我不知道正式术语那)。也就是说,所有参数必须具有相同的类型,并且 thisconst 限定必须相同。如果有任何不匹配,派生的 class 中的方法将隐藏 所有具有相同名称的方法,而不是覆盖。这就是您图片中的“错误”试图告诉您的内容。所以 // overrides 在该图片的评论中是不正确且具有误导性的。

是的,很多C++老师其实并不理解这些有些晦涩的细节。

顺便说一句,如果你想覆盖,你的基础class中的方法应该是virtual;否则,多态性将不起作用。如果不是virtual,我们也说derived-class方法隐藏了base-class方法。然而,这里关于隐藏的部分几乎没有任何意义;这个词真正想表达的是你没有压倒一切。

此外,正如您所注意到的,重载 存在多个具有相同名称但不同签名的方法。它们都应该出现在派生 class 中才有用——如果派生 class 只有一种方法 fa1,而其他 fa1 在基础中,它们将被隐藏。但是,有语法糖将所有 fa1 从基础“复制”到派生,禁用所有 hiding 语义:

class A
{
public:
    void fa1();
    void fa1(int);
};

class B: public A
{
public:
    using A::fa1;
    void fa1(int, int);
};

...
B b;
b.fa1(); // calls A::fa1()
b.fa1(4); // calls A::fa1(int)
b.fa1(4, 8); // calls B::fa1(int, int)

关于隐藏的部分很少(如果有的话)有用。重写时,你应该告诉你的编译器——为此使用 override 关键字。然后,编译器将检查您的代码是否按预期工作。

class A
{
public:
    virtual void fa1(int) {}
    void fa2(int) {}
};

class B: public A
{
public:
    void fa1(int) override {} // OK
    void fa1() override {} // ERROR: doesn't really override - different signature
    void fa2(int) override {} // ERROR: doesn't really override - not virtual in base
};