假设我有一个带有虚拟方法的接口,但其中一个参数是:
virtual void Delete(ParentClass *parentClass) = 0;
如果我以后在子类中实现它
void Delete(ChildClass *childClass)
{
};
...为什么这不能作为实现工作?
假设我有一个带有虚拟方法的接口,但其中一个参数是:
virtual void Delete(ParentClass *parentClass) = 0;
如果我以后在子类中实现它
void Delete(ChildClass *childClass)
{
};
...为什么这不能作为实现工作?
由于函数原型不同(一个用途ParentClass
和另一个用途ChildClass
),它们不是相同的功能。相反,带有ChildClass
参数的那个是重载而不是覆盖Delete
函数。
C++03 标准:10.3/2
vf
如果在一个类中声明一个虚拟成员函数,Base
并且在一个类Derived
中直接或间接地派生自一个与声明的具有相同名称和相同参数列表Base
的成员函数,那么它也是虚拟的并且被它覆盖。vf
Base::vf
Derived::vf
Base::vf
注意粗体字。
派生类函数仅覆盖基类函数,并且仅当它具有与基类函数相同的签名,但协变返回类型除外。由于您的函数Delete()
在基类和派生类中没有相同的签名,因此派生类函数不会覆盖基类函数,而您得到的只是Function Hiding。
C++03 标准:3.3.7/1:
可以通过在嵌套声明区域或派生类中显式声明相同名称来隐藏名称。
因为任何被接受为基类函数参数的类型,也必须被该函数的覆盖所接受。这可以防止错误,例如:
struct BastardClass : ParentClass {} wrong;
Delete(&wrong);
如果将其分派到期望 a 的覆盖ChildClass
,则会导致它将对象解释为错误的类型。
(这被称为逆变- 被更具体类型覆盖的函数的参数不能比被覆盖的参数更具体。出于类似的原因,返回类型必须是协变的 - 由更具体类型覆盖的函数指定的那些必须是同样具体。)