【问题标题】:Resolution of inherited member functions, based on parameters' types [duplicate]基于参数类型的继承成员函数的解析[重复]
【发布时间】:2013-06-20 18:14:47
【问题描述】:

在问我的问题之前,我尝试在网上搜索,但我不确定我需要使用哪些术语,也没有找到对我的问题的解释。如果已经存在这样的答案,请随时指出我:)

这是一个小样本:

class IObject;
class ClassA;

class Base {
public: void Method(IObject * object) {}
};

class Derived : public Base {
public: void Method(ClassA * objet) {}
};

class IObject {};
class ClassA : public IObject {};

int main(int argc, char ** argv) {
    IObject * object = new ClassA();
    Derived derived;
    derived.Method(object);
    delete object;
    return 0;
}

这不会编译,因为编译器尝试使用该方法的 Derived::Method 版本,即使给定对象存在完全有效的 Base::Method。

为了使这个编译(和工作),我需要在 Derived 中添加以下内容:

class Derived : public Base {
public:
    // adding this line make the Base::Method visible to the compiler ??
    using Base::Method;
    void Method(ClassA * object) {}
};

添加此行后,一切都按预期工作。 我不明白的是:为什么?如果我将 Base::Method 重命名为 Base::BaseMethod,我可以毫无问题地从 Derived 实例调用它。为什么编译器无法根据参数的类型找到正确的方法??

【问题讨论】:

  • 是的,现在我知道要使用哪些术语(例如“函数隐藏”),我找到了很多答案和重复的问题 :)

标签: c++


【解决方案1】:

此规则在 C++ 中称为 Function hiding。
派生类中与基类方法同名的方法隐藏派生类中的基类方法。派生类的用户只能看到派生类的方法,而与函数参数类型无关。基类方法根本不存在于派生类范围内。因此,重载决议不会像您期望的那样工作。
为了能够访问派生类中的基类方法,您需要明确告诉编译器使用 using 声明将其引入派生类范围。

【讨论】:

  • 也感谢您提供的链接。据我了解,引入此规则是为了避免隐式转换出现问题。很高兴知道:)
【解决方案2】:

这称为成员函数隐藏:一旦派生类中的函数与基类中具有相同名称的函数具有不同的签名,则基类版本的函数对派生类及其客户是不可见的。 Here's 引入这个的原因。

【讨论】:

  • 感谢您的回答!
猜你喜欢
  • 2021-08-09
  • 1970-01-01
  • 2013-09-10
  • 1970-01-01
  • 2012-05-16
  • 2015-08-22
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
相关资源
最近更新 更多