鉴于以下情况:
#include <vector>
struct Widget
{
void doThing()
{
...
}
};
struct SpecialWidget : public Widget
{
void doSpecialThing()
{
...
}
};
int main()
{
std::vector<Widget*> widgets;
widgets.push_back(new Widget());
widgets.push_back(new SpecialWidget());
...
for(auto& w : widgets)
{
w->doThing();
//Also need to call doSpecialThing() if element is a SpecialWidget
}
return 0;
}
在这里正确的做法是将doSpecialThing()
声明为基类Widget
中的虚函数,并且什么都不做吗?我相当确定答案是否定的。在那种情况下,有没有更好的方法来解决这个问题?
亲切的问候
答案 0 :(得分:3)
虚拟函数应始终位于基类中。在不是基类的任何类中添加virtual
关键字不会有任何效果。
我们还可以通过显式指定相关函数的范围来调用函数的基类版本。
如果您可以将doSpecialThing
更改为doThing
,则您的代码可以简单地变成:
struct Widget
{
//make virtual for dynamic function binding with Widget pointers
virtual void doThing()
{
...
}
};
struct SpecialWidget : public Widget
{
void doThing()
{
Widget::doThing();
...
}
};
或者如果您希望将其保留为doSpecialThing
:
struct Widget
{
//make virtual for dynamic function binding with Widget pointers
virtual void doThing()
{
...
}
};
struct SpecialWidget : public Widget
{
void doThing() {
Widget::doThing();
doSpecialThing();
}
void doSpecialThing()
{
...
}
};
答案 1 :(得分:0)
您正在交换许多不同的函数名称,但是从我的收集中,您希望有一个派生类调用其自己的doThing(),然后让基类在其后立即调用其doThing(),这完全可以接受
#include <vector>
struct Widget{
virtual void doThing()
{
cout << "Base" << endl;
}
};
struct SpecialWidget : public Widget
{
void doThing()
{
cout << "Derived" << endl;
Widget::doThing();
}
};
尽管我对C ++有点生锈,但我相信这会起作用,但输出会是
Derived
Base
答案 2 :(得分:0)
作为我的评论的扩展,如果您希望SpecialWidget
与基础doThing()
一起做一些特殊的事情,更好的方法是覆盖{{1}中的doThing()
},如下所示:
SpecialWidget
并正常调用其他所有内容。