【问题标题】:Virtual function being redefined in other base classes在其他基类中重新定义虚函数
【发布时间】:2020-03-04 09:48:31
【问题描述】:

考虑这段代码sn-p:

#include <bits/stdc++.h>
using namespace std;

class Mammal;
class Operation;

class Animal{
    public:
        virtual void doOp(Operation* op) = 0;
};

class Mammal{
    public:
        void doOp(Operation* op){
            op->thisIsMammal(this);
        }
};

class Pig:  public Mammal, public Animal{

};

class Operation{
    public: 
        void thisIsMammal(Mammal* mammal){
            cout << "This is a mammal!" << endl;
        }
};

int main(){
    Pig  pig;
    Operation op;
    pig.doOp(&op);
    return 0;
}

Animal 类中声明了一个虚函数,需要在Pig 类中重新定义。但是,Pig 派生自 Mammal,具有该函数的定义

我仍然收到该函数尚未在派生类中重新定义的错误。有什么方法可以使Mammal 中的定义足够?

【问题讨论】:

  • 不,C++ 不能以这种方式工作。您必须在子类中声明虚函数,并让子类的函数显式调用实现超类中的实现。
  • 也许this 是怎么回事?
  • 您可能还想研究/使用override specifier。

标签: c++ oop overriding multiple-inheritance virtual-functions


【解决方案1】:

您的代码中的Mammal 不是从Animal 派生的,因此它不能真正覆盖虚函数Animal::doOp()。代码中成员函数Mammal::doOp() 的定义只是定义了一个名为doOp() 的非virtual 函数。它不会覆盖任何内容。

考虑使用override 说明符(C++11 起)。

如果您在认为要在 Mammal 中覆盖 doOp() 时使用了 override specifier,则在此阶段会出现编译错误,因为以下成员函数定义不会覆盖 doOp():

class Mammal{
    public:
        void doOp(Operation* op) override {
            op->thisIsMammal(this);
        }
};

【讨论】:

    【解决方案2】:

    然而,Pig 是从 Mammal 派生的,具有此功能的定义

    不,它没有。 Mammal 不会覆盖函数Animal::doOp,因为Mammal 不会继承Animal。

    一个简单的解决方案是从Animal 派生Mammal,并从Pig 中删除Animal 基:

    class Mammal : public Animal {
    
    class Pig :  public Mammal {
    

    【讨论】:

    • 看,我打算建议虚拟继承。我更喜欢这个。
    • @Chipster 虚拟继承是一个非常锋利的工具,几乎从不使用,如果使用,它只能由真正知道自己在做什么的专家来完成(恕我直言)。
    • @JesperJuhl 虚拟继承最大的危害是什么?
    • 很难决定哪个更糟 - 问题中的多重继承,或答案中的多重继承。
    猜你喜欢
    • 1970-01-01
    • 2011-04-12
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多