多态:从基本指针访问派生成员函数

时间:2018-08-20 22:18:18

标签: c++ inheritance polymorphism

鉴于以下情况:

#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中的虚函数,并且什么都不做吗?我相当确定答案是否定的。在那种情况下,有没有更好的方法来解决这个问题?

亲切的问候

3 个答案:

答案 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

并正常调用其他所有内容。