我的代码与此相同:
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 继承,但我不会&#39;不知道是什么。也许有一些功能可以在C ++中重命名冲突名称?
PS&GT;我不能使用C ++ 11,只能使用旧的C ++ 98。
答案 0 :(得分:1)
<强> TL; DR 强>
在课程foo
中覆盖D
。由于不相关的foo
和X
返回类型,Y
方法无法协变。两者都不能因为不同的返回类型而重载,但签名相同。
<强> 解释 强>
让我们将代码清理为具有相同问题的较小代码段:
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
继承了foo
和A
中的两个C<Y>
方法。这两个导入的方法可以共存,因为它们来自不同的父级,可以通过限定的调用来调用它们,例如D d; d.A::foo();
。
但是在这种情况下,当您尝试覆盖课程foo
中的D
时,问题会出现在图片中:
/*virtual*/ Y * foo() {};
在课程D
中,有一个方法X * foo()
继承自A
,您将覆盖方法Y * foo()
。这些不能协变,because Y
is not derived from X
。另一方面,此foo
不能超载另一个Because return type is not part of function signature。
阅读clang的错误信息很好:
错误:返回类型的虚函数'foo'与。不协调 它覆盖的函数的返回类型('Y *'不是从'X'派生的 *')
virtual Y * foo() {};
<强> 解决方案 强>
最好的解决方案是简化您的设计并摆脱这些复杂的继承,模板化和同名方法!!
答案 1 :(得分:0)
您说您不需要在foo
中声明的C<X>
方法并在A
中实施,但由于您的班级D
也是 - { {1}}和A
客户端可能依赖于此方法可用,并返回C<X>
。 C ++不支持删除继承的方法AFAIK,因为这会违反Liskov替换原则。
如果您在此处删除或隐藏X
,则C<X>::foo
,D
或{{1}的实例无法使用A
的实例} 是期待。所以我担心这里没有解决这个问题的好办法。如果您只是尝试重用B
中的C<X>
或A
中的实现,那么在这种情况下您可能应该考虑使用合成而不是继承。
答案 2 :(得分:-1)