C++ 在子类中重载虚函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8816794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overloading a virtual function in a child class
提问by Vijay
I am just testing with virtual keyword and inheritance concepts in c++. I have written a small program:
我只是在 C++ 中使用 virtual 关键字和继承概念进行测试。我写了一个小程序:
#include<stdio.h>
#include<iostream>
using namespace std;
class cna_MO
{
public:
virtual void print()
{
cout << "cna_MO" << endl;
}
};
class cna_bsc:public cna_MO
{
public:
void print()
{
cna_MO::print();
}
void print(int a)
{
cout << "cna_BSC" << endl;
}
};
class cna_Mo
{
cna_MO *_mo;
public:
cna_Mo()
{
_mo = new cna_bsc;
}
virtual void print(int a)
{
cout << "cna_Mo with arg" << endl;
_mo->print(5);
}
virtual void print()
{
cout << "cna_Mo" << endl;
_mo->print();
}
};
int main()
{
cna_Mo valid_mo;
cout << "old case is started" << endl;
valid_mo.print();
cout << "new case is started" << endl;
valid_mo.print(5);
return 0;
}
What I have done here is I have overloaded a virtual function in parent class in child class! Is this not the right thing to do?
我在这里所做的是我在子类的父类中重载了一个虚函数!这不是正确的做法吗?
I am getting the compilation errors as below:
我收到如下编译错误:
"temp10.cc", line 45: Error: Too many arguments in call to "cna_MO::print()".
“temp10.cc”,第 45 行:错误:调用“cna_MO::print()”的参数过多。
回答by Alok Save
Once you overload a function from Base class in Derived class all functions with the same name in the Base class get hidden in Derived class.
一旦您从派生类中的基类中重载函数,基类中具有相同名称的所有函数都会隐藏在派生类中。
Once you added the function cna_bsc::print(int a)
to your derived class the function cna_MO::::print()
is no longer visible to users of the Derived class. This is known as function hiding.
将函数添加cna_bsc::print(int a)
到派生类cna_MO::::print()
后,派生类的用户将不再看到该函数。这称为函数隐藏。
Solution:In order to make the hidden function visible in derived class, You need to add:
解决方案:为了使隐藏函数在派生类中可见,您需要添加:
using cna_MO::print;
in the public
section of your derived class cna_bsc
.
在public
派生类的部分cna_bsc
。
Good Read:
好读:
What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?
回答by matiu
It's because the print function in the child class takes a parameter and the original doesn't.
这是因为子类中的打印函数需要一个参数,而原始函数没有。
in cna_MO (parent class):
在 cna_MO(父类)中:
virtual void print()
in cna_bsc (child class):
在 cna_bsc(子类)中:
void print(int a)
Basically the child's print should not take an int argument:
基本上孩子的打印不应该采用 int 参数:
void print()
EDIT:
编辑:
Maybe the best would be to make passing the int optional ?
也许最好的办法是让 int 成为可选的?
eg:
例如:
in cna_MO (parent class):
在 cna_MO(父类)中:
virtual void print(int a=-1) {
if (a == -1) {
// Do something for default param
} else {
cout << a;
}
}
in cna_bsc (child class):
在 cna_bsc(子类)中:
void print(int a=-1)
so if a == -1 you can probably assume, they didn't pass anything.
所以如果 a == -1 你可以假设,他们没有通过任何东西。
The trick is that both the parent and child need the same method siganture, meaning same return type and the same argument types.
诀窍是父和子都需要相同的方法签名,这意味着相同的返回类型和相同的参数类型。
回答by liaK
When you have a function with same name and different parameters in the derived class as that of the base class, then that function will be hidden. You can find more info here..
当派生类中的函数与基类的函数名称相同但参数不同时,该函数将被隐藏。你可以在这里找到更多信息..
You can call the specific hidden function by calling like Base::hiddenFun();
您可以通过调用来调用特定的隐藏函数 Base::hiddenFun();
回答by visitor
That can't work because given a cna_MO *
, you can see at compile-time that the pointed object does not (necessarily) have the int overload. If it actually pointed to a base-class object, _mo->print(5);
would really have nothing to call. Also there can be an infinite number of (not yet implemented) derived classes that don't have to support this call.
这是行不通的,因为给定 a cna_MO *
,您可以在编译时看到指向的对象(必然)没有 int 重载。如果它实际上指向一个基类对象,_mo->print(5);
就真的没有什么可调用的了。此外,可能有无数(尚未实现)派生类不必支持此调用。
Every derived class must have
print(int)
- declare it in the base class.Every derived class need not have
print(int)
-cna_Mo
only works withcna_bsc
, so the member should becna_bsc* _mo
.
每个派生类都必须
print(int)
- 在基类中声明它。每一个派生类不需要有
print(int)
-cna_Mo
只有工作cna_bsc
,所以该成员应该是cna_bsc* _mo
。
回答by CashCow
Ideally your print that takes an int should have a different name but given you want both functions to be called print, you should make them both non-virtual and make them call protected virtual functions.
理想情况下,您使用 int 的打印应该具有不同的名称,但是如果您希望两个函数都被称为打印,您应该将它们都设为非虚拟函数并让它们调用受保护的虚拟函数。
class cna_MO
{
public:
void print() { doPrint(); }
protected:
virtual void doPrint()
{ cout << "cna_MO" << endl;
}
};
class cna_bsc:public cna_MO
{
protected:
virtual void doPrint()
// although with implementation no need to override it
{
cna_MO::print();
}
public:
void print(int a)
{
doPrintInt( a );
}
protected:
virtual void doPrintInt( int )
{
cout << "cna_BSC" << endl;
}
};
回答by Mr Lister
If you REALLY MUST do it like this, i.e. have a pointer to one class and initialise as a derived class, there's no choice but to always cast the pointer to the correct type when using it. In this case, ((cna_bsc*)_mo)->print(5);
如果您真的必须这样做,即有一个指向一个类的指针并初始化为派生类,则别无选择,只能在使用时始终将指针强制转换为正确的类型。在这种情况下,((cna_bsc*)_mo)->print(5);