C++:覆盖还是重载?

C++: override or overload?

我有两个 classes 表示某些方法的上下文。

class BaseContext {};
class DerivedContext : public BaseContext {};

我有一个基地class:

class MyBase {
protected:
  virtual void doSome(BaseContext* context);
};

和派生的class:

class MyDerived : public MyBase {
protected:
  virtual void doSome(DerivedContext* context) override; // Overriding
  virtual void doSome(DerivedContext* context); // Overloading?
};

由于 DerivedContext 派生自 BaseContext,因此我似乎覆盖了 doSome。但这也可能是超载...

  1. 哪个是正确的?我在这里是覆盖还是超载?
  2. 因此,如果我输入 (MyBase* my = new MyDerived())->doSome(new DerivedContext()),我应该得到什么?

这既不是覆盖也不是超载。由于参数的类型不同,MyDerived::doSome只是隐藏 MyBase::doSome.

1.1. Since DerivedContext derives from BaseContext, it might seems that I am overriding doSome.

没有。这是标准中列出的覆盖的先决条件。 $10.3/2 虚拟函数 [class.virtual]:

(强调我的)

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides110 Base::vf.

110) A function with the same name but a different parameter list (Clause [over]) as a virtual function is not necessarily virtual and does not override.

实际上对于这种情况 override specifier you'll get a compile error。例如

error: 'doSome' marked 'override' but does not override any member functions

1.2. But it might also be an overloading...

can't overload functions across scopes according to the rule of unqualified name lookup (unless using using-declaration 将名称引入同一范围)。

  1. Thus, if I type (MyBase* my = new MyDerived())->doSome(new DerivedContext()), what should I get?

MyBase::doSome() 将被调用,因为您在 MyBase* 上调用它。这不是覆盖,所以这里没有动态调度发生。

LIVE

注意参数 DerivedContext* 将隐式转换为 BaseContext* 然后传递给函数。顺便说一句 (MyBase* my = new MyDerived())->... 是无效语法。

只需在函数定义之后放置override 并查看它是否编译。如果它编译,它会覆盖基 class 中的虚拟方法。如果没有,它将 隐藏 基本 class 方法。

虽然只指定了具有另一种参数类型的成员函数,但您从基类中隐藏了该函数 class。
使用 override 说明符你应该得到一个编译错误,因为在基 class.

中没有这样的函数(具有完全相同的签名)

重写是当重新定义派生的class中的虚成员函数时与完全相同参数(数字类型)。 override 说明符是可选的,但鼓励使用它,因为它有助于识别您的情况下的细微错误。

重载 是指使用不同数量或类型的参数定义函数(不一定是 class 的成员)。