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

Posted

技术标签:

【中文标题】多态性:从基指针访问派生成员函数【英文标题】:Polymorphism: Accessing derived member function from base pointer 【发布时间】:2018-08-20 22:18:18 【问题描述】:

鉴于以下情况:

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

亲切的问候

【问题讨论】:

你想要SpecialWidgetdoSpecialThing() 而不是doThing()?如果是这样,只需覆盖doThing()。如果您想要 doSpecialThing()doThing() 和其他东西,请再次覆盖并事先明确调用 Widget::doThing() 【参考方案1】:

虚函数应该总是在基类中。在不是基类的任何类中添加 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()
    
        ...
    
;

【讨论】:

【参考方案2】:

您有一堆不同的函数名称正在互换,但据我所知,您希望派生类调用它自己的 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

【讨论】:

【参考方案3】:

作为我评论的扩展,如果您希望 SpecialWidget 与基本 doThing() 一起做一些特别的事情,更好的方法是在 SpecialWidget 中覆盖 doThing(),如下所示:

struct SpecialWidget : public Widget

    void doThing()
    
        Widget::doThing();
        ...
    
;

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

【讨论】:

以上是关于多态性:从基指针访问派生成员函数的主要内容,如果未能解决你的问题,请参考以下文章

如果基类指针不能访问派生类成员函数,那么多态有啥方便呢?

当有多个派生类时,如何使用基类指针访问派生类的函数成员?

c ++设计:从基类转换为派生类,没有额外的数据成员

实验五——类的多态,继承和派生2

从基类指针访问两个具有不同类型的派生成员变量。

6多态性-3虚函数