啊,所以及时回来了。
我犯了一个奇怪的错误:
'B::blah': overriding virtual function return type differs and is not covariant from 'A::blah'
造成问题的代码如下:
class A {
public:
class Inner { };
virtual Inner blah() = 0;
};
class B : public A {
public:
class Inner2 : public Inner { };
Inner2 blah() {
return Inner2();
}
};
我查找了错误,根据我在微软网站上找到的一页,类型可以是协变的方式之一是:
返回类型B::f中的类与返回类型D::f中的类相同,是返回类型D::f中类的一个明确的直接或间接基类,在D中可以访问
Inner
和Inner2
的情况不是这样吗?如果重要的话,我正在使用微软的VisualC++ 2010。
好的,多亏了John,我知道只有指针和引用可以是协变的。为什么会这样呢?派生的函数可以转换为Base,那么为什么不使用派生自同一事物的返回类型的虚拟函数将返回类型转换为基类之一呢?在我的例子中,让(A*(new B))->blah()
返回一个实际上已经被抛出的Inner2
的Inner
似乎是有意义的。
发布于 2011-08-06 13:29:37
只有指针和引用可以是协变的。
发布于 2013-05-28 02:00:32
假设你的例子奏效了。
考虑以下代码:
A *a = some_function();
A::Inner inner = a->blah();
如果动态类型的a
为B*,则a->blah()
调用a::B->blah()
,并返回B::Inner
。然后将其静默地切片到A::Inner
的一个实例中。一般来说,这(和任何类型的切片)不是你想要的。我觉得这是个很好的限制。
发布于 2011-08-06 14:19:53
如果您的请求被允许,这意味着通过基类对blah()的调用必须从Inner2转换到内部.转换是不可能的,因为调用方负责管理返回的对象(因为它不是由指针/引用返回,而是通过值返回),并将在堆栈上为其保留空间。因此,它只能处理内部类,而不能处理Inner2或其他祖先类。
所以你有了一个内部的例子,而不是Inner2.所以你没有任何优势..。
https://stackoverflow.com/questions/6969020
复制