首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >协变量返回类型和类型转换

协变量返回类型和类型转换
EN

Stack Overflow用户
提问于 2015-01-25 03:20:50
回答 2查看 1K关注 0票数 9

s->duplicate()返回一个Box*类型的对象,但是我得到了一个用Box*初始化它的错误。看起来它正在被转换回Shape*。如果将协变量返回类型转换回基类指针,有什么意义?:

代码语言:javascript
复制
struct Shape
{
    virtual Shape* duplicate()
    {
        return new Shape;
    }
};

struct Box : Shape
{
    virtual Box* duplicate()
    {
        return new Box;
    }
};

int main()
{
    Shape* s = new Box;
    Box*   b = s->duplicate();
}

错误:

代码语言:javascript
复制
main.cpp:22:12: error: cannot initialize a variable of type 'Box *' with an rvalue of type 'Shape *'
    Box*   b = s->duplicate();
           ^   ~~~~~~~~~~~~~~
1 error generated.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-09 20:44:31

虽然Box::duplicate在运行时被调用(通过虚拟调度),尽管Box::duplicate确实覆盖Shape::duplicate (共变),尽管Box::duplicate确实返回Box*,但是仍然会得到一个Shape*指针,因为您通过Shape*指针调用duplicate(),而Shape*Shape::duplicate()的返回类型,编译器只看到您调用Shape::duplicate,而不是Box::duplicate

C++不能动态地选择类型,所以这是它所能做的最好的。您的Box*将在退出Box::duplicate时自动转换为Shape*。正如Barry所说,“它仍然必须在编译时编译,在编译时我们只知道它返回一个Shape*”。

然后,要再次将其转换为Box*,您需要显式地转换它(使用static_castdynamic_cast),因为不存在隐式向下转换。

[C++11: 10.3/7]: 重写函数的返回类型应该是,或者与重写函数的返回类型相同,或者与函数类的协变量相同。。。 [C++11: 10.3/8]:如果D::f的返回类型与B::f的返回类型不同,则返回类型D::f中的类类型应在D::f声明点完成,或者为类类型D。当重写函数被调用为被重写函数的最后一个覆盖项时,其结果将转换为(静态选择的)重写函数 (5.2.2)返回的类型。。。

在标准文本中,下面是一个相关的示例。

票数 11
EN

Stack Overflow用户

发布于 2015-01-25 03:28:31

重点不在于这样做:

代码语言:javascript
复制
Box*   b = s->duplicate();

这显然不能工作,因为Shape::duplicate()返回一个Shape*。相反,如果要在Box*上直接调用duplicate(),则需要接受Box

代码语言:javascript
复制
Box* old = new Box;
Box* b = old->duplicate(); // OK! We know it's a Box
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28132869

复制
相关文章

相似问题

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