为什么C ++不支持跨范围重载?

时间:2016-06-16 13:58:05

标签: c++ overloading name-hiding

我相信这里已经给出了最好的答案:Why does an overridden function in the derived class hide other overloads of the base class?

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

  

为了覆盖此行为,用户需要显式操作:最初是对继承方法的重新声明(当前已弃用),现在显式使用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. 我可以假设,w.r.t派生类对象,int f(int i)函数根本不存在。由于名称隐藏,这不是继承的。

  2. 如果我必须在Derived类中使用此函数,我必须在派生类中再次定义它吗?

1 个答案:

答案 0 :(得分:4)

  
      
  1. 我可以假设,w.r.t派生类对象,int f(int i)函数根本不存在。由于名称隐藏,这不会继承。
  2.   

继承,它只是...... 隐藏,如果您没有指定范围,则无法找到( unqualified name lookup。您可以使用范围解析运算符::qualified name lookup)明确指定它:

dp->Base::f(3);
  
      
  1. 如果我必须在Derived类中使用此函数,我必须在派生类中再次定义它?
  2.   

正如引用的答案所说,你可以用&#34;明确使用using-declaration&#34;来实现。

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

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

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

是的,你可以。它仍然隐藏着名字。

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

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

  

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