1

我相信这里已经给出了最好的答案:为什么派生类中的重写函数会隐藏基类的其他重载?

但我有点困惑,特别是声明:

为了覆盖此行为,需要用户进行显式操作:最初是重新声明继承的方法(当前已弃用),现在显式使用 using-declaration。

假设我有以下程序:

#include <iostream>
using namespace std;
class Base
{
public:
    int f(int i)
    {
        cout << "f(int): ";
        return i+3;
    }
};
class Derived : public Base
{
public:
    double f(double d)
    {
        cout << "f(double): ";
        return d+3.3;
    }
};
int main()
{
    Derived* dp = new Derived;
    cout << dp->f(3) << '\n';
    cout << dp->f(3.3) << '\n';
    delete dp;
    return 0;
}

我有两个问题:

  1. 我可以假设,wrt 派生类对象,该int f(int i)函数根本不存在。由于名称隐藏,这不是继承的。

  2. 如果我必须在派生类中使用这个函数,我必须在派生类中重新定义它吗?

4

1 回答 1

4
  1. 我可以假设,wrt 派生类对象, int f(int i) 函数根本不存在。由于名称隐藏,这不是继承的。

继承的,只是... hidden,如果不指定范围(非限定名称查找)则无法找到。您可以使用范围解析运算符::限定名称查找)显式指定它:

dp->Base::f(3);
  1. 如果我必须在派生类中使用这个函数,我必须在派生类中重新定义它吗?

正如引用的答案所说,您可以通过“明确使用 using-declaration”来做到这一点。

class Derived : public Base
{
public:
    using Base::f;
    ...
};

编辑(来自评论的补充问题)

  1. 如果它的名字是隐藏的,那意味着我可以再次声明它?相同的名称,相同的参数?

是的你可以。还是隐姓埋名。

  1. 如果是,如果我还添加using Base::f了新声明怎么办?会导致双重定义吗?

不,这不是双重定义。使用声明只是将名称引入派生类范围。而在派生类中声明的成员函数会隐藏从基类引入的成员函数,它仍然是名称隐藏。(请注意,您仍然可以通过 调用基类之一dp->Base::f(3);。)

如果派生类已经有一个具有相同名称、参数列表和限定条件的成员,则派生类成员隐藏或覆盖(不与)从基类引入的成员。

于 2016-06-16T14:05:49.480 回答