继承破坏了 C++ 中的多态性?

Posted

技术标签:

【中文标题】继承破坏了 C++ 中的多态性?【英文标题】:Inheritance mucking up polymorphism in C++? 【发布时间】:2009-12-11 18:30:08 【问题描述】:

也许我对继承和多态的了解并不是我想象的那样。有人能解释一下吗?

设置(问题的简单化):

class X 
;

class Y 
;

class Base 
  public:
    void f( X* ) 
;

class Child: public Base 
  public:
    void f( Y* ) 
;

问题:这应该可行,对吧?

int main( void ) 
  X* x = new X();
  Y* y = new Y();
  Child* c = new Child();
  c->f( x );
  c->f( y );
  return 0;

我收到错误(GCC 4.4):

`no matching function for call to 'Child::f(X*&)'`
`note: candidates are: void Child::f(Y*)`

【问题讨论】:

名称隐藏。这个问题每天被问 3 次。请参阅常见问题解答parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9 你的意思是让你的两个班级被称为A和B吗? 也许我看错了,但你确定 f 的参数应该是 A 和 B 吗? 他的错误信息显示他的真实代码中没有AB。这只是一个错字。我更正了来源。 谢谢,@AndreyT - 我最初有 A、B、C 和 D,但太混乱了。 【参考方案1】:

virtual 关键字在这里对您没有帮助。

您的基类Base::f 被派生类型隐藏。您需要执行以下操作:

class Child: public Base 
  public:
    using Base::f;
    void f( Y* ) 
;

Parashift goes into more detail.

【讨论】:

好的,我不知道你可以在这样的课程中“使用” - 谢谢。无论如何,我对名称隐藏的概念非常熟悉 - 但它真的 ONLY 基于函数名称,而不是整个签名吗? 是的,按名称查找发生在重载决议之前,因此Base::f 不被视为重载而不显式拉入它们。【参考方案2】:

您的派生类'f()隐藏基类'f()。您可以通过将Base::f() 显式引入派生类的范围来防止这种情况:

class Child: public Base 
  public:
    using Base::f;
    void f( Y* ) 
;

【讨论】:

【参考方案3】:

已经回答了:

Why does an overridden function in the derived class hide other overloads of the base class?

当你在派生类上声明一个方法时,它会从基类中隐藏任何同名的方法。

【讨论】:

以上是关于继承破坏了 C++ 中的多态性?的主要内容,如果未能解决你的问题,请参考以下文章

C++多态知识点深入了解

C++多态

C++多态

C++:多态公有继承中的虚方法

C++之多态总结(多态的定义及实现,抽象类,多态原理,单继承,多继承中的虚函数表)

C++——多态