在问我的问题之前,我尝试在网上搜索,但我不确定我需要使用哪些条款,而且我没有找到解决问题的方法。如果这样的答案已经存在,请随意指出:)
这是一个小样本:
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实例中调用它而不会有任何问题。为什么编译器无法根据参数的类型??
找到正确的方法答案 0 :(得分:3)
此规则在C ++中称为 Function hiding
派生类中与Base类方法具有相同名称的方法隐藏派生类中的基类方法。派生类的用户只能看到派生类方法,而不管函数参数类型如何。 Derived类作用域中根本不存在基类方法。因此,重载分辨率无法按预期工作。
为了能够在派生类中访问Base类方法,您明确需要告诉编译器使用using声明将它带入派生类范围。
答案 1 :(得分:2)
这称为成员函数隐藏:只要在派生类中有一个函数,其签名与基类中具有相同名称的函数不同,那么基类版本的函数对派生类及其客户端是不可见的。 Here's之所以引入这个原因。