【问题标题】:C++ - Overloading vs Overriding in InheritanceC ++ - 继承中的重载与覆盖
【发布时间】:2022-01-02 09:18:35
【问题描述】:

据我所知,重写是指您有 2 个函数具有相同的名称和函数返回类型(voidintfloat.. 等)以及相同的参数编号和类型。

重载是当您有 2 个函数名称相同但参数编号/类型或函数返回类型应该不同时。

但是今天我在上课的时候,看到了这张幻灯片:

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

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

【问题讨论】:

  • ia1 不会覆盖,它只是将成员隐藏在基类中(这是狡猾的,永远不应该在实际代码中完成)。你也是对的,函数是重载的,而不是被覆盖的。
  • fa1 不是virtual。祝你好运。当幻灯片稍后提出隐藏时,幻灯片又回到了这个问题,但总的来说我讨厌这张幻灯片。太误导人了。

标签: c++ oop inheritance overriding overloading


【解决方案1】:

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

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

【讨论】:

  • "ia1 绝对是一个覆盖" - 不,您既不能“覆盖”也不能“重载”变量。正确的术语是“影子”。
【解决方案2】:

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

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

另外,如果你想重写,你的基类中的方法应该是virtual;否则,多态性将不起作用。如果不是virtual,我们也说派生类方法隐藏基类方法。然而,这里关于隐藏的部分几乎没有任何意义;这个词真正想要表达的是你没有压倒一切。

此外,重载正如您所注意到的,存在多个名称相同但签名不同的方法。它们都应该存在于派生类中才能发挥作用——如果派生类只有一个方法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
};

【讨论】:

  • 好答案,但有一个细节:派生类中的函数永远不会覆盖基类中的非虚函数,即使参数类型、cv-qualifiers 和 ref-qualifiers 都是完全正确的相同。 “覆盖”只能在基本功能为虚拟时适用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
  • 1970-01-01
  • 2019-06-29
  • 2018-07-26
  • 1970-01-01
相关资源
最近更新 更多