Val*_* T. 5 c++ multiple-inheritance covariant c++98
我有与此等效的代码:
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!
};
Run Code Online (Sandbox Code Playgroud)
我收到这个错误:
error: invalid covariant return type for 'virtual Y* D::foo()'
Y * foo() {};
^
Run Code Online (Sandbox Code Playgroud)
和:
error: overriding 'virtual X* A::foo()'
X * foo() {};
^
Run Code Online (Sandbox Code Playgroud)
我相信我可以在B类或D类中编写一些内容来阻止A::foo继承,但我不知道是什么。也许 C++ 中有一些重命名冲突名称的功能?
PS> 我不能使用 C++11,只能使用旧的 C++98。
长话短说
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>
};
Run Code Online (Sandbox Code Playgroud)
那么,类从和D继承了两个foo方法。这两个导入的方法可以共存,因为它们来自不同的父方法,并且可以通过限定调用来调用它们,例如.AC<Y>D d; d.A::foo();
foo但在这种情况下,当您尝试在类中重写时,问题就出现了D:
/*virtual*/ Y * foo() {};
Run Code Online (Sandbox Code Playgroud)
在类中D,有一个方法的签名X * foo()继承自A并且您正在重写方法Y * foo()。这些不能协变,因为Y不是源自X。另一方面,这foo不能重载另一个,因为返回类型不是函数签名的一部分。
看看clang的错误信息就好了:
错误:虚拟函数“foo”的返回类型与它覆盖的函数的返回类型不协变(“Y *”不是从“X *”派生的)
Run Code Online (Sandbox Code Playgroud)virtual Y * foo() {};
解决方案
最好的解决方案是简化你的设计并摆脱这些复杂的继承、模板化和同名方法!