多继承的模糊解决方法?

Nik*_*las 5 c++ multiple-inheritance

我有一个叫做动物的基类,一个继承自Animal的狗和一只猫.还有一个名为dogcat的多继承类,它继承自dog和cat,在Animal中我有一个名为sleep的方法.当我想从dogcat使用那个方法时,我得到错误"DogCat :: sleep"是模棱两可的,我确实理解了这个问题,但我在一本书中读到,当你将睡眠宣布为虚拟时它应该是可能的 - 但它不起作用.

这不可能是书错了还是有任何解决方法?

class Animal
{
public:
    Animal(){}

    virtual void sleep()
    {
        cout << "zzzzzzzzz" << endl;
    }
    virtual void eat() = 0;

};

class Dog: public Animal
{
protected:
    Dog(){}

    virtual void eat() override
    {
        cout << "eats dogfood" << endl;
    } 
};

class Cat :public Animal
{
public:
    Cat(){}
    virtual void eat() override
    {
        cout << "eats catfood" << endl;
    }
};

class DogCat : public Dog, public Cat
{
public:
    DogCat(){}
    using Dog::eat;

};

int main(int argc, char** argv) {
    DogCat *DC = new DogCat();
    DC->sleep();//Error
}
Run Code Online (Sandbox Code Playgroud)

amc*_*con 6

你有钻石问题

在此输入图像描述

"钻石问题"(有时被称为"致命的死亡钻石"[4])是一种歧义,当两个B和C类继承自A,而D类继承自B和C时产生歧义.如果存在A中B和C重写的方法,D不覆盖它,然后D继承的方法版本:B的那个,还是C的那个?

所以.现在你有两个A.实例是什么解决方案?你有两个:

  1. 在其中一个子子句中定义睡眠操作并调用它:
class Cat :public Animal
{
    public:
        Cat(){}
        virtual void eat() override
        {
            cout << "eats catfood" << endl;
        }

        void sleep()
        {
            Animal::sleep();
        }
};

int main(int argc, char** argv) {
    DogCat *DC = new DogCat();
    DC->Cat::sleep();
}
Run Code Online (Sandbox Code Playgroud)
  1. 像@Asesh回答一样使用虚拟继承.问题是常见的方法eat().你必须覆盖它.

  • 您可以通过调用`Cat :: sleep`来删除`Cat :: sleep`但实现`DogCat :: sleep`,它将自然地通过`Cat`路径调用`Animal :: sleep`. (2认同)