为什么 C++ 不支持跨范围重载? [英] Why C++ does not support overloading across scopes?

查看:68
本文介绍了为什么 C++ 不支持跨范围重载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

<块引用>

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

假设我有以下程序:

#include 使用命名空间标准;班级基地{上市:int f(int i){cout<<"f(int):";返回 i+3;}};派生类:公共基础{上市:双 f(双 d){cout<<"f(double):";返回 d+3.3;}};int main(){派生* dp = 新派生;cout<<dp->f(3)<<'\n';cout<<dp->f(3.3)<<<'\n';删除dp;返回0;}

我有两个问题:

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

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

解决方案

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

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

dp->Base::f(3);

<块引用>

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

正如引用的答案所说,您可以通过显式使用 using 声明"来实现.

class Derived : public Base{上市:使用 Base::f;...};

编辑(针对评论中的补充问题)

<块引用>

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

是的,你可以.它仍然隐藏名称.

<块引用>

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

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

<块引用>

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

I believe that the best answer is already given here : Why does an overridden function in the derived class hide other overloads of the base class?

But I am confused a little bit, specially with the statement :

In order to override this behavior, an explicit action is required from the user: originally a redeclaration of inherited method(s) (currently deprecated), now an explicit use of using-declaration.

Suppose I have the following program :

#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;
}

I have two questions :

  1. Can I assume, w.r.t derived class object, the int f(int i) function does not exist at all. This is not inherited because of name hiding.

  2. If I have to use this function in Derived class, I have to define it again in derived class?

解决方案

  1. Can I assume, w.r.t derived class object, the int f(int i) function does not exist at all. This is not inherited because of name hiding.

It is inherited, it's just ... hidden, can't be found if you don't specify the scope (unqualified name lookup. You can specify it explicitly with scope resolution operator :: (qualified name lookup) :

dp->Base::f(3);

  1. If I have to use this function in Derived class, I have to define it again in derived class?

As the quoted answer said, you can do it with "an explicit use of using-declaration".

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

EDIT (for supplemental questions from comment)

  1. If it's name hidden, that means I can declare it again ? Same name, same parameters?

Yes, you can. It's still name hiding.

  1. If yes, what if I also added using Base::f along with the new declaration? Will it result in double definition?

No, it's not double definition. Using declaration just introduces the name into the derived class scope. And the member function declared in derived class will hide the one introduced from base class, it's still name hiding. (Note you still could call the one of base class by dp->Base::f(3);.)

If the derived class already has a member with the same name, parameter list, and qualifications, the derived class member hides or overrides (doesn't conflict with) the member that is introduced from the base class.

这篇关于为什么 C++ 不支持跨范围重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆