![](/img/trans.png)
[英]C++ Multiple inheritance, virtual method override problems, and covariant return type
[英]C++ covariant return type error with multiple inheritance
我有与此相同的代码:
class X {};
class Y {};
template< typename T>
class C {
public:
virtual T * foo() = 0;
};
class A : public C< X> {
public:
X * foo() {};
};
class B : public A {};
class D : public B, public C< Y> {
public:
Y * foo() {}; //this is the only one method I need here. Not A::foo!
};
我有这个错误:
error: invalid covariant return type for 'virtual Y* D::foo()'
Y * foo() {};
^
和:
error: overriding 'virtual X* A::foo()'
X * foo() {};
^
我相信我可以在B类或D 类中写一些东西以防止A :: foo继承,但我不知道是什么。 也许有一些功能可以在C ++中重命名冲突名称?
PS>我不能使用C ++ 11,只能使用旧的C ++ 98。
TL; DR
在D
级覆盖foo
。 由于不相关的X
和Y
返回类型, foo
方法无法协变。 两者都不能因为不同的返回类型而重载,但签名相同。
说明
让我们将代码清理为具有相同问题的较小代码段:
class X {};
class Y {};
template<typename T>
class C {
public:
virtual T * foo() = 0;
};
class A : public C<X> {
public:
// Your code:
// X * foo() {}; <---- This method is irrelevant to the problem
// virtual X * foo() {};
// ^^^^^^^^^^^^^^^^^^^^^
// This method declared via inheritance and template
// and implicitly exists in this class, (look at keyword `virtual`)
};
class D : public A, public C<Y> {
public:
/*virtual*/ Y * foo() {}; // `virtual` comes from C<X>
};
好吧, D
类继承了A
和C<Y>
两个foo
方法。 这两种导入的方法可以共存,因为它们来自不同的父母,可以通过合格的调用来调用,例如D d; dA::foo();
D d; dA::foo();
。
但是在这种情况下,当你尝试在D
类中覆盖foo
时,问题会出现在图片中:
/*virtual*/ Y * foo() {};
在D
类中,有一个带有签名X * foo()
的方法,它继承自A
,你重写方法Y * foo()
。 这些不能协变, 因为Y
不是从X
派生的 。 另一方面,这个foo
不能重载另一个, 因为返回类型不是函数签名的一部分 。
阅读clang的错误信息很好:
错误:虚函数'foo'的返回类型与它覆盖的函数的返回类型不一致('Y *'不是从'X *'派生的)
virtual Y * foo() {};
解
最好的解决方案是简化您的设计并摆脱这些复杂的继承,模板化和同名方法!
你说你不需要在C<X>
声明并在A
实现的foo
方法,但由于你的D
类也是A
和C<X>
,客户端可能依赖于这种方法可用,并返回一个X
C ++不支持删除继承的方法AFAIK,并且有充分的理由,因为这会违反Liskov替换原则。
如果你在这里删除或隐藏了C<X>::foo
,那么在预期A
, B
或C<X>
的实例的情况下,不能使用D
的实例。 所以我担心这里没有解决这个问题的好办法。 如果您只是尝试在D
重用A
或B
中的实现,那么在这种情况下您可能应该考虑组合而不是继承。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.