请考虑以下内容:
#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'
为什么需要注释的方法来进行编译?
答案 0 :(得分:5)
因为与您标记的内容不同,您没有具有钻石继承权。您的sparrow
是两个animal
,bird
将其中只有一个具体化。通过landAnimal
继承的另一个不是。
要获得实际的钻石,您需要的是虚拟继承,但是您会发现它附带了一个详尽的警告清单。
顺便提一句,正如Martin Bonner正确指出的那样:
可能值得指出的是,“修复”根本不是修复。对
sparrow::speak()
的任何调用都将导致无限递归。它应该是std::string speak() { return Bird::speak(); }
。