I am trying to understand why the following code does not compile, apparently the solution relies in specifically declaring the dependency on method_A in the derived class. Please refer to the following code:
我试图理解为什么下面的代码不能编译,显然解决方案依赖于在派生类中明确声明对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) The wrong number of arguments have been specified for "Derived::method_A(int)".
“test.cpp”,(S)为“Derived :: method_A(int)”指定了错误的参数数量。
What is the technical reason that prevents the derived class to know its base class is implementing the method it's trying to overload? I am looking in understanding better how the compiler/linker behaves in this case.
什么是阻止派生类知道其基类的技术原因是实现它试图重载的方法?我正在寻找更好地理解编译器/链接器在这种情况下的行为。
3 个解决方案
#1
35
Its called Name Hiding. When you define a non virtual method with the same name as Base method it hides the Base class method in Derived class so you are getting the error for
它叫名字隐藏。当您定义一个与Base方法同名的非虚方法时,它会隐藏Derived类中的Base类方法,因此您将收到错误
myDerived.method_A(1,2);
To avoid hiding of Base class methods in Derived class use using keyword as you did in Derived2 class.
为了避免在Derived类中隐藏Base类方法,请像在Derived2类中一样使用关键字。
Also if you want to make it work you can do it explictly
此外,如果你想让它工作,你可以明确地做到这一点
myDerived.Base::method_A(1,2);
Check out this for better explanation why name hiding came into picture.
看看这个是为了更好地解释为什么隐藏名称隐藏起来。
#2
0
Well, for one you're calling
嗯,对于你正在打电话的人
myDerived.method_A(1,2);
with 2 arguments, whereas both in base and derived the method is declared to take only one argument.
使用2个参数,而在base和derived中,声明方法只接受一个参数。
Secodnly, you're not overriding anything, because method_A is not virtual. You're overloading.
最后,你没有覆盖任何东西,因为method_A不是虚拟的。你正在超载。
#3
-1
If your intention is to override void Base::method_A(int param, int param2)
then you should mark it virtual in the base class:
如果您的目的是覆盖void Base :: method_A(int param,int param2),那么您应该在基类中将其标记为虚拟:
virtual void method_A(int param, int param2)
Any function overriding this must have the same parameters and almost the same return type ('almost' loosely meaning that the differing return types must be polymorphically related, but in most cases it should have the identical return type).
任何覆盖它的函数必须具有相同的参数和几乎相同的返回类型('几乎'松散地意味着不同的返回类型必须是多态相关的,但在大多数情况下它应该具有相同的返回类型)。
All you're currently doing is overloading the function in the base class. The using
keyword is bringing the base class function into the child class' namespace, as the language behaviour is not to do this by default.
您目前所做的只是在基类中重载函数。 using关键字将基类函数引入子类的命名空间,因为默认情况下语言行为不会这样做。
#1
35
Its called Name Hiding. When you define a non virtual method with the same name as Base method it hides the Base class method in Derived class so you are getting the error for
它叫名字隐藏。当您定义一个与Base方法同名的非虚方法时,它会隐藏Derived类中的Base类方法,因此您将收到错误
myDerived.method_A(1,2);
To avoid hiding of Base class methods in Derived class use using keyword as you did in Derived2 class.
为了避免在Derived类中隐藏Base类方法,请像在Derived2类中一样使用关键字。
Also if you want to make it work you can do it explictly
此外,如果你想让它工作,你可以明确地做到这一点
myDerived.Base::method_A(1,2);
Check out this for better explanation why name hiding came into picture.
看看这个是为了更好地解释为什么隐藏名称隐藏起来。
#2
0
Well, for one you're calling
嗯,对于你正在打电话的人
myDerived.method_A(1,2);
with 2 arguments, whereas both in base and derived the method is declared to take only one argument.
使用2个参数,而在base和derived中,声明方法只接受一个参数。
Secodnly, you're not overriding anything, because method_A is not virtual. You're overloading.
最后,你没有覆盖任何东西,因为method_A不是虚拟的。你正在超载。
#3
-1
If your intention is to override void Base::method_A(int param, int param2)
then you should mark it virtual in the base class:
如果您的目的是覆盖void Base :: method_A(int param,int param2),那么您应该在基类中将其标记为虚拟:
virtual void method_A(int param, int param2)
Any function overriding this must have the same parameters and almost the same return type ('almost' loosely meaning that the differing return types must be polymorphically related, but in most cases it should have the identical return type).
任何覆盖它的函数必须具有相同的参数和几乎相同的返回类型('几乎'松散地意味着不同的返回类型必须是多态相关的,但在大多数情况下它应该具有相同的返回类型)。
All you're currently doing is overloading the function in the base class. The using
keyword is bringing the base class function into the child class' namespace, as the language behaviour is not to do this by default.
您目前所做的只是在基类中重载函数。 using关键字将基类函数引入子类的命名空间,因为默认情况下语言行为不会这样做。