多继承的模糊解决方法?

时间:2016-10-09 12:03:50

标签: c++ multiple-inheritance

我有一个名为animal的基类,以及一个继承自Animal的狗和猫。 还有一个名为dogcat的多继承类,它继承自狗和猫, 在动物我有一个叫做睡眠的方法。当我想从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
}

2 个答案:

答案 0 :(得分:6)

您拥有diamond problem

enter image description here

  

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

因此。现在你有两个A.实例是什么解决方案?你有两个:

  1. 在其中一个子子句中定义睡眠操作并调用它:
  2. 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();
    }
    
    1. 使用虚拟继承,如@Asesh回答。问题是常见的方法eat()。你必须覆盖它。

答案 1 :(得分:3)

您应该使用虚拟继承

class Animal
{
public:
    Animal(){}

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

};

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

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

class Cat : virtual 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
}