C++;继承与函数重写 在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; }

C++;继承与函数重写 在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; },c++,inheritance,overriding,C++,Inheritance,Overriding,这就是所谓的“隐藏”:Y::spray隐藏X::spray。 使用指令添加: class Y : public X { public: using X::spray; // ... }; 用于描述这一点的术语是“隐藏”,而不是“覆盖”。默认情况下,派生类的成员将使具有相同名称的基类的任何成员都不可访问,无论它们是否具有相同的签名。如果要访问基类成员,可以使用声明将它们拉入派生类中。在这种情况下,将以下内容添加到Y类中: using X::spray; 类是作用域,类作用域嵌套在其

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

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

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

using X::spray;

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


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

感谢您的解释,这使它变得清晰。当我在这里添加using指令时,它就起作用了。但是,当我在X中将spray签名更改为spray(int),在Y中更改为spray(float),并调用Y.spray(1);y.喷雾(1.0f);它在没有using指令的情况下工作。为什么?哇,对不起,我的坏,当我做Y时,它仍然只看到Y的喷雾(浮动);It类型强制int(int)浮点。这是一个值得自己特殊的答案,用大量的搜索粉末编写,这样人们可以更好地找到它。得到了C++ FAQ,它是关于同一个问题的,如果有人需要它,就可以进行详细的解释:)说签名应该是相同的,这有点危险。签名是名称篡改和链接的基础。不同类的两个成员始终具有不同的签名,即使其中一个覆盖另一个。我认为最好说“相同的参数类型、名称和常量”,即使说的时间更长。@litb:谢谢你的澄清!我想“原型”这个词在这里很贴切,我在问题中对它做了修改:)谢谢你解释了背后的原因;它确实说明了为什么我首先会遇到这个错误,以及为什么using指令解决了这个问题。
using X::spray;