0

假设我有一个带有虚拟方法的接口,但其中一个参数是:

virtual void Delete(ParentClass *parentClass) = 0;

如果我以后在子类中实现它

void Delete(ChildClass *childClass)
{
};

...为什么这不能作为实现工作?

4

3 回答 3

1

由于函数原型不同(一个用途ParentClass和另一个用途ChildClass),它们不是相同的功能。相反,带有ChildClass参数的那个是重载而不是覆盖Delete函数。

于 2012-08-27T14:22:23.730 回答
0

C++03 标准:10.3/2

vf如果在一个类中声明一个虚拟成员函数,Base并且在一个类Derived中直接或间接地派生自一个与声明的具有相同名称和相同参数列表Base的成员函数那么它也是虚拟的并且被它覆盖。vf Base::vfDerived::vfBase::vf

注意粗体字。
派生类函数仅覆盖基类函数,并且仅当它具有与基类函数相同的签名,但协变返回类型除外。由于您的函数Delete()在基类和派生类中没有相同的签名,因此派生类函数不会覆盖基类函数,而您得到的只是Function Hiding

C++03 标准:3.3.7/1:

可以通过在嵌套声明区域或派生类中显式声明相同名称来隐藏名称。

于 2012-08-27T15:04:02.520 回答
0

因为任何被接受为基类函数参数的类型,也必须被该函数的覆盖所接受。这可以防止错误,例如:

struct BastardClass : ParentClass {} wrong;
Delete(&wrong);

如果将其分派到期望 a 的覆盖ChildClass,则会导致它将对象解释为错误的类型。

(这被称为逆变- 被具体类型覆盖的函数的参数不能比被覆盖的参数更具体。出于类似的原因,返回类型必须是协变的 - 由具体类型覆盖的函数指定的那些必须是同样具体。)

于 2012-08-27T15:12:45.267 回答