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; // ... }; 用于描述这一点的术语是隐藏,而不是覆盖。默认情况下,派生类的成员将使具有相同名称的基类的任何成员都不可访问,无论它们是否具有相同的签名。如果要访问基类成员,可以使用using声明将它们拉入派生类。在这种情况下,将以下内容添加到类Y中: 类是作用域,类作用域嵌套在其父级中。与其他嵌套作用域、命名空间

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

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

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


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


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

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