我有两个类代表某些方法的上下文。
class BaseContext {};
class DerivedContext : public BaseContext {};
我有一个基类:
class MyBase {
protected:
virtual void doSome(BaseContext* context);
};
派生类:
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())
,我该怎么办?答案 0 :(得分:4)
这既不是重写也不是超载。由于参数的类型不同,<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header"></div>
<div id="content">
<ul>
<li>some text</li>
<li>some text</li>
</ul>
</div>
只是隐藏 MyDerived::doSome
。
1.1。由于
MyBase::doSome
来自DerivedContext
,我似乎可能会覆盖BaseContext
。
没有。这是标准中列出的重写的前提条件。 $10.3/2 Virtual functions [class.virtual]:
(强调我的)
如果在类
doSome
和类vf
中声明虚拟成员函数Base
,直接或间接地从Derived
派生,则成员函数{{1声明具有相同名称, parameter-type-list ([dcl.fct]),cv-qualification和ref-qualifier(或不存在相同),Base
,然后vf
也是虚拟的(无论是否如此声明)并且覆盖 110Base::vf
。110)具有相同名称但不同参数列表(Clause [over])作为虚函数的函数不一定是虚函数,不会覆盖。
事实上,对于override specifier,你会得到compile error这个案例。 e.g。
Derived::vf
1.2。但它也可能是一个超载......
根据can't overload规则,您unqualified name lookup跨范围发挥作用(除非使用using-declaration将名称引入同一范围)。
因为您在
- 因此,如果我输入
醇>Base::vf
,我该怎么办?
error: 'doSome' marked 'override' but does not override any member functions
上调用它,所以会调用 (MyBase* my = new MyDerived())->doSome(new DerivedContext())
。这不是重写,因此这里不会发生动态调度。
注意,参数MyBase::doSome()
将隐式转换为MyBase*
,然后传递给函数。 BTW DerivedContext*
是无效的语法。
答案 1 :(得分:1)
虽然只使用另一个参数类型指定成员函数,但是您正在从基类中隐藏该函数
使用override
说明符,您应该得到编译错误,因为基类中没有这样的函数(具有完全相同的签名)。
覆盖是使用完全相同的参数(数字和在派生类中重新定义虚拟成员函数的时间>类型)。 override
说明符是可选的,但我鼓励它,因为它有助于识别您的情况下的细微错误。
重载是在定义具有不同数量或类型的参数的函数(不一定是类的成员)时。
答案 2 :(得分:0)
在函数定义之后放置override,看看它是否编译。如果它编译,它将覆盖基类中的虚方法。如果没有,它将隐藏基类方法。