此问题已在此处有答案:
Why does an overridden function in the derived class hide other overloads of the base class?(4个答案)
2天前关闭。
下面是一个简单的例子,它再现了我遇到的问题:
class Base
{
public:
Base() {}
Base(int value) {}
Base& operator[](int index) { return Base(); }
Base& operator[](const char* index) { return Base(); }
};
class IntChild : public Base
{
Base& operator[](const char* index) = delete;
};
IntChild test;
test[4] = 1; //Error: no operator "[]" matches these operands
在基类中实现了两个运算符[]。在子类中删除以const char*
为参数的运算符。但是,当子类中的operator[](const char*)
被删除时,使用运算符取integer
时也会发生错误:
没有运算符“[]”匹配这些操作数
我正在使用Visual Studio 2019。
我错过了什么?
1条答案
按热度按时间2skhul331#
使用Base::operator[];在派生类中将其引入作用域:
下面是using-declaration的相关摘录,它解释了为什么在添加using之后,你可以在基类中调用
int
-重载:在类定义中
Using-declaration将基类的成员引入到派生类定义中,例如将基类的受保护成员公开为派生的公共成员。在这种情况下,nested-name-specifier必须命名正在定义的基类。如果名称是基类的重载成员函数的名称,则引入具有该名称的所有基类成员函数。如果派生类已经有一个具有相同名称、参数列表和限定的成员,则派生类成员将隐藏或重写(不与之冲突)从基类引入的成员。
为什么没有
using
,它不会退回到基类operator[](int)
的问题可以用unqualified name lookup来回答(特别是下面的b点):类定义
对于在类定义(包括基类说明符和嵌套类定义)中任何地方使用的名称,除了在成员函数体内部、成员函数的默认参数、成员函数的异常说明或默认成员初始化器内部,其中成员可能属于定义在封闭类的主体中的嵌套类,搜索以下范围:
a)在使用点之前使用名称的类的主体
B)其基类的整个主体,当找不到声明时递归到它们的基类
因此,一旦在派生类中找到一个声明,就不必继续在基类中搜索函数。请注意,当你实现派生类时,这也成立(不仅仅是当你
=delete
它时)。