“无效的协变返回类型"嵌套类中的错误,方法返回基于模板的对象
以下 C++ 代码在编译时给了我这些错误:
The following C++ code gives me these errors when compiled:
covariant.cpp:32:22: error: invalid covariant return type for ‘virtual Q<B> C::test()’
covariant.cpp:22:22: error: overriding ‘virtual Q<A> B::test()’
我不想更改行 virtual Qtest() {}
到 virtual Qtest() {}
虽然它消除了编译错误.有没有其他方法可以解决这个问题?
I do not want to change the line virtual Q<B> test() {}
to virtual Q<A> test() {}
although it removes the compilation errors. Is there another way to solve this problem?
template <class T>
class Q
{
public:
Q() {}
virtual ~Q() {}
};
class A
{
public:
A() {}
virtual ~A() {}
};
class B
{
public:
B() {}
virtual ~B() {}
virtual Q<A> test() = 0;
};
class C : public B
{
public:
C() {}
virtual ~C() {}
virtual Q<B> test() {}
};
推荐答案
Q
和 Q
是不相关的类.假设您是 B
调用 test()
的客户端:如果您不知道结果是什么类型,您将结果分配给什么类型?
Q<B>
and Q<A>
are unrelated classes. Imagine you are a client of B
calling test()
: what do you assign the result to, if you do not know what type it is going to have?
Q
和 Q
都是同一个类模板的实例这一事实并没有改变它们是两个完全不相关的类的事实,可能具有完全不同的布局(由于模板专业化).
The fact that both Q<A>
and Q<B>
are instances of the same class template does not change the fact that they are two completely unrelated classes, possibly with a completely different layout (due to template specialization).
这与做没有什么不同:
struct X
{
virtual std::string test() = 0;
};
struct Y : X
{
virtual int test() { return 42; } // ERROR! std::string and int are
// unrelated, just as Q<A> and Q<B>
};
客户端在指向 X
的指针上调用 test()
会期望结果是 string
,但是哎呀!",该指针指向的对象是Y
类型,Y::test()
的返回类型是int
.应该发生什么?运行时崩溃?
The client calling test()
on a pointer to X
would expect the result to be a string
, but "Whoops!", the object pointed to by that pointer is of type Y
, and the return type of Y::test()
is int
. What should happen? A run-time crash?
Y y;
X* p = &y;
std::string s = p->test(); // D'OH!
C++ 是一种静态类型语言,这意味着在编译时执行类型检查.在这种情况下,来自编译器的消息会告诉您派生类不遵守其派生类的接口.
C++ is a statically typed language, meaning that type checking is performed at compile-time. In this case, the message from the compiler is there to tell you that the derived class does not adhere to the interface of the class it derives from.
如果您想知道无效的协变返回类型"是什么意思,特别是协变"这个词,那很容易解释.
If you are wondering what "invalid covariant return type" means, and in particular the word "covariant", that's easily explained.
假设你有一个基类 B
和一个虚函数 foo()
返回一个 X*
:
Suppose you have a base class B
with a virtual function foo()
that returns an X*
:
struct B
{
virtual X* foo();
};
假设您有一个从 B
派生的类 D
,它通过返回 Y*
,其中 Y
是从 X
派生的类:
And suppose that you have a class D
derived from B
that overrides foo()
by returning an Y*
, where Y
is a class derived from X
:
struct D : B
{
virtual Y* foo();
};
这是一个问题吗?好吧,正确的答案来自回答这个稍微好一点的问题:对于调用 foo()
的客户端来说,这会是一个问题吗?它期望 X*
回来了?"
Is this a problem? Well, the right answer comes from answering this slightly better question: "Would that be a problem for a client calling foo()
that expects an X*
to be returned?"
这个问题的答案显然是否定的,因为Y
是X
的派生类,所以你可以返回一个指向Y
而不是指向 X
的指针:
And the answer to that question is obviously "No", since Y
is a derived class of X
, so you can return a pointer to Y
instead of a pointer to X
:
D d;
B* b = &d;
X* p = b->foo(); // Returns an Y*, but that's OK, because a pointer to Y can be
// assigned to a pointer to X
这是协变返回类型的示例.在您的示例中,C::test()
的返回类型与 B::test()
的返回类型不协变.
This is an example of a covariant return type. In your example, the return type of C::test()
is not covariant with respect to the return type of B::test()
.
相关文章