为什么我必须显式定义由inhereed类提供的方法?

时间:2018-07-31 14:22:49

标签: c++ inheritance diamond-problem

请考虑以下内容:

#include <string>

struct animal
{
public:
    virtual std::string speak() = 0;
};

struct bird : public animal
{
public:
    std::string speak()
    {
        return "SQUAK!";
    }
};

struct landAnimal : public animal
{
    virtual int feet() = 0;
};


struct sparrow : public bird, public landAnimal
{
    int feet() { return 2; }
    // This solves it, but why is it necessary, doesn't bird provide this?
    // std::string speak(){ return this->speak(); } 
};

int main()
{
    sparrow tweety = sparrow();
}

编译它,您将得到:

1>ex.cpp(35): error C2259: 'sparrow': cannot instantiate abstract class
1>  ex.cpp(35): note: due to following members:
1>  ex.cpp(35): note: 'std::string animal::speak(void)': is abstract
1>  ex.cpp(10): note: see declaration of 'animal::speak'

为什么需要注释的方法来进行编译?

1 个答案:

答案 0 :(得分:5)

因为与您标记的内容不同,您没有具有钻石继承权。您的sparrow是两个animalbird将其中只有一个具体化。通过landAnimal继承的另一个不是。

要获得实际的钻石,您需要的是虚拟继承,但是您会发现它附带了一个详尽的警告清单。

顺便提一句,正如Martin Bonner正确指出的那样:

  

可能值得指出的是,“修复”根本不是修复。对sparrow::speak()的任何调用都将导致无限递归。它应该是std::string speak() { return Bird::speak(); }