c++ - 为什么我必须显式定义继承类提供的方法?

标签 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'

为什么需要注释方法才能编译?

最佳答案

因为,与您标记的不同,您没有继承钻石。你的麻雀是两只动物,其中只有一只被bird具体化了。另一个通过 landAnimal 继承的不是。

要获得真正的钻石,您需要的是虚拟继承,但您会发现它附带了大量警告。

旁注,如Martin Bonner正确地指出:

It's probably worth pointing out that the "fix" isn't a fix at all. Any call to sparrow::speak() will cause infinite recursion. It would need to be std::string speak() { return Bird::speak(); }.

关于c++ - 为什么我必须显式定义继承类提供的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51615667/

相关文章:

没有 '\n' 或 endl 的 C++ 输出字符串将在字符串末尾输出 '#'

c++ - 在 C++ 字符串中替换的最佳方法是什么?

c++ - 如何在不将其添加到项目的情况下通过 xcode 运行 .cpp 文件?

c++ - 如何用具体类之一实例化抽象类?

C++ TCP recv 未知缓冲区大小

c++ - 可以为间接基类共享基类实例吗?

inheritance - 多态性没有像我想象的那样工作?

c++ - g++ "because the following virtual functions are pure"带抽象基类

python - Python/Django 中多抽象模型继承中的字段菱形模式

python - 什么是 Python 中的菱形继承(钻石问题),为什么它没有出现在 python2 中?