【问题标题】:C++ inheritance and function overridingC++ 继承和函数覆盖
【发布时间】:2011-01-10 19:31:04
【问题描述】:

在 C++ 中,基类的成员函数是否会被其同名的派生类函数覆盖,即使其原型(参数的计数、类型和常量)不同?我想这是一个愚蠢的问题,因为许多网站都说函数原型应该是相同的。但是为什么下面的代码不能编译?我相信这是一个非常简单的继承案例。

#include <iostream>
using std::cout;
using std::endl;

class A {};
class B {};

class X
{
public:
    void spray(A&)
    {
        cout << "Class A" << endl;
    }
};

class Y : public X
{
public:
    void spray(B&)
    {
        cout << "Class B" << endl;
    }
};

int main()
{
    A a;
    B b;
    Y y;

    y.spray(a);
    y.spray(b);

    return 0;
}

GCC 抛出

error: no matching function for call to `Y::spray(A&)'
note: candidates are: void Y::spray(B&)

【问题讨论】:

  • 得到了关于同一问题的 C++ 常见问题解答,如果有人需要,请详细解释:) parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9
  • 说签名应该一样有点危险。签名是名称修改和链接的基础。不同类的两个成员总是有不同的签名,即使一个覆盖另一个。我认为最好说“相同的参数类型、名称和常量”,即使说的时间更长。
  • @litb:感谢您的澄清!我想“原型”在这里是恰当的词,我在问题中改变了它:)

标签: c++ inheritance overriding


【解决方案1】:

用于描述这一点的术语是“隐藏”,而不是“覆盖”。默认情况下,派生类的成员将使具有相同名称的基类的任何成员无法访问,无论它们是否具有相同的签名。如果要访问基类成员,可以使用using 声明将它们拉入派生类。在这种情况下,将以下内容添加到class Y

using X::spray;

【讨论】:

  • 感谢您的解释,说明清楚了。当我在此处添加 using 指令时,它可以工作。但是当我将喷雾签名更改为 X 中的 spray(int) 和 Y 中的 spray(float) 并调用 y.spray(1);和 y.spray(1.0f);它可以在没有 using 指令的情况下工作。怎么会?
  • 哇,对不起,我的错,当我做 y.spray(1); 时,它仍然只看到 Y 的喷雾(浮动);它类型将 int 类型强制转换为隐式浮动。
  • 这是值得拥有自己特殊问题的答案之一,它使用大量搜索粉精心制作,以便人们可以更好地找到它。
【解决方案2】:

这就是所谓的“隐藏”:Y::spray 隐藏X::spray。 添加 using 指令:

class Y : public X
{
public:
   using X::spray;
   // ...
};

【讨论】:

    【解决方案3】:

    类是作用域,类作用域嵌套在其父级中。您与其他嵌套范围(命名空间、块)具有完全相同的行为。

    发生的情况是,当名称查找搜索名称的定义时,它会在当前命名空间中查找,然后在 englobing 命名空间中查找,以此类推,直到找到一个定义;然后搜索停止(这没有考虑到参数依赖名称查找引入的复杂性 - 允许使用在其参数之一的命名空间中定义的函数的规则部分)。

    【讨论】:

    • 感谢您解释阻碍背后的根本原因;它确实说明了为什么我首先遇到该错误以及为什么 using 指令解决了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多