2

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

这是一个小样本:

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 实例调用它。为什么编译器无法根据参数的类型找到正确的方法??

4

2 回答 2

3

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

于 2013-06-24T09:28:16.180 回答
2

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

于 2013-06-24T09:32:52.197 回答