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
。但这也可能是超载...
- 哪个是正确的?我在这里是覆盖还是超载?
- 因此,如果我输入
(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 将名称引入同一范围)。
- Thus, if I type
(MyBase* my = new MyDerived())->doSome(new DerivedContext())
, what should I get?
MyBase::doSome()
将被调用,因为您在 MyBase*
上调用它。这不是覆盖,所以这里没有动态调度发生。
注意参数 DerivedContext*
将隐式转换为 BaseContext*
然后传递给函数。顺便说一句 (MyBase* my = new MyDerived())->...
是无效语法。
只需在函数定义之后放置override 并查看它是否编译。如果它编译,它会覆盖基 class 中的虚拟方法。如果没有,它将 隐藏 基本 class 方法。
虽然只指定了具有另一种参数类型的成员函数,但您从基类中隐藏了该函数 class。
使用 override
说明符你应该得到一个编译错误,因为在基 class.
中没有这样的函数(具有完全相同的签名)
重写是当重新定义派生的class中的虚成员函数时与完全相同参数(数字和类型)。 override
说明符是可选的,但鼓励使用它,因为它有助于识别您的情况下的细微错误。
重载 是指使用不同数量或类型的参数定义函数(不一定是 class 的成员)。
我有两个 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
。但这也可能是超载...
- 哪个是正确的?我在这里是覆盖还是超载?
- 因此,如果我输入
(MyBase* my = new MyDerived())->doSome(new DerivedContext())
,我应该得到什么?
这既不是覆盖也不是超载。由于参数的类型不同,MyDerived::doSome
只是隐藏 MyBase::doSome
.
1.1. Since
DerivedContext
derives fromBaseContext
, it might seems that I am overridingdoSome
.
没有。这是标准中列出的覆盖的先决条件。 $10.3/2 虚拟函数 [class.virtual]:
(强调我的)
If a virtual member function
vf
is declared in a classBase
and in a classDerived
, derived directly or indirectly fromBase
, a member functionvf
with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) asBase::vf
is declared, thenDerived::vf
is also virtual (whether or not it is so declared) and it overrides110Base::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 将名称引入同一范围)。
- Thus, if I type
(MyBase* my = new MyDerived())->doSome(new DerivedContext())
, what should I get?
MyBase::doSome()
将被调用,因为您在 MyBase*
上调用它。这不是覆盖,所以这里没有动态调度发生。
注意参数 DerivedContext*
将隐式转换为 BaseContext*
然后传递给函数。顺便说一句 (MyBase* my = new MyDerived())->...
是无效语法。
只需在函数定义之后放置override 并查看它是否编译。如果它编译,它会覆盖基 class 中的虚拟方法。如果没有,它将 隐藏 基本 class 方法。
虽然只指定了具有另一种参数类型的成员函数,但您从基类中隐藏了该函数 class。
使用 override
说明符你应该得到一个编译错误,因为在基 class.
重写是当重新定义派生的class中的虚成员函数时与完全相同参数(数字和类型)。 override
说明符是可选的,但鼓励使用它,因为它有助于识别您的情况下的细微错误。
重载 是指使用不同数量或类型的参数定义函数(不一定是 class 的成员)。