我试图理解为什么以下代码无法编译,显然该解决方案依赖于在派生类中明确声明对method_A的依赖。 请参考以下代码:
class Base
{
public:
void method_A(int param, int param2)
{
std::cout << "Base call A" << std::endl;
}
};
//does not compile
class Derived : public Base
{
public:
void method_A(int param)
{
std::cout << "Derived call A" << std::endl;
}
};
//compiles
class Derived2 : public Base
{
public:
using Base::method_A; //compile
void method_A(int param)
{
std::cout << "Derived call A" << std::endl;
}
};
int main ()
{
Derived myDerived;
myDerived.method_A(1);
myDerived.method_A(1,2);
Derived2 myDerived2;
myDerived2.method_A(1);
myDerived2.method_A(1,2);
return 0;
}
“test.cpp”,(S)为“Derived :: method_A(int)”指定了错误的参数数。
阻止派生类知道其基类的技术原因是什么实现了它试图重载的方法? 我正在寻找更好地理解编译器/链接器在这种情况下的行为。
答案 0 :(得分:35)
它被称为名称隐藏。当您定义一个与Base方法同名的非虚方法时,它会隐藏Derived类中的Base类方法,因此您将收到
的错误 myDerived.method_A(1,2);
为了避免在Derived类中隐藏隐藏Base 类方法,请像在Derived2类中一样使用关键字。
另外,如果你想让它发挥作用,你可以明确地做到这一点
myDerived.Base::method_A(1,2);
查看this以更好地解释为什么隐藏名称隐藏起来。
答案 1 :(得分:0)
嗯,对于你正在打电话的人
myDerived.method_A(1,2);
有2个参数,而在base和derived中,声明方法只接受一个参数。
Secodnly,你没有覆盖任何东西,因为method_A不是虚拟的。你正在超载。
答案 2 :(得分:-1)
如果您打算覆盖 void Base::method_A(int param, int param2)
,那么您应该在基类中将其标记为虚拟:
virtual void method_A(int param, int param2)
任何覆盖它的函数必须具有相同的参数且几乎相同的返回类型('几乎'松散意味着不同的返回类型必须是多态相关的,但在大多数情况下它应该具有相同的返回类型)。
您目前所做的只是重载基类中的函数。 using
关键字将基类函数带入子类的命名空间,因为默认情况下语言行为不会这样做。