首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >重写虚拟函数返回类型不同,且不是协变量。

重写虚拟函数返回类型不同,且不是协变量。
EN

Stack Overflow用户
提问于 2011-08-06 21:27:42
回答 6查看 13.6K关注 0票数 9

啊,所以及时回来了。

我犯了一个奇怪的错误:

代码语言:javascript
代码运行次数:0
运行
复制
 'B::blah': overriding virtual function return type differs and is not covariant from 'A::blah'

造成问题的代码如下:

代码语言:javascript
代码运行次数:0
运行
复制
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中可以访问

InnerInner2的情况不是这样吗?如果重要的话,我正在使用微软的VisualC++ 2010。

好的,多亏了John,我知道只有指针和引用可以是协变的。为什么会这样呢?派生的函数可以转换为Base,那么为什么不使用派生自同一事物的返回类型的虚拟函数将返回类型转换为基类之一呢?在我的例子中,让(A*(new B))->blah()返回一个实际上已经被抛出的Inner2Inner似乎是有意义的。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-08-06 21:29:37

只有指针和引用可以是协变的。

票数 18
EN

Stack Overflow用户

发布于 2013-05-28 10:00:32

假设你的例子奏效了。

考虑以下代码:

代码语言:javascript
代码运行次数:0
运行
复制
A *a = some_function();
A::Inner inner = a->blah();

如果动态类型的a为B*,则a->blah()调用a::B->blah(),并返回B::Inner。然后将其静默地切片到A::Inner的一个实例中。一般来说,这(和任何类型的切片)不是你想要的。我觉得这是个很好的限制。

票数 3
EN

Stack Overflow用户

发布于 2011-08-06 22:19:53

如果您的请求被允许,这意味着通过基类对blah()的调用必须从Inner2转换到内部.转换是不可能的,因为调用方负责管理返回的对象(因为它不是由指针/引用返回,而是通过值返回),并将在堆栈上为其保留空间。因此,它只能处理内部类,而不能处理Inner2或其他祖先类。

所以你有了一个内部的例子,而不是Inner2.所以你没有任何优势..。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6969020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档