协变量返回类型和类型转换 [英] Covariant return type and type conversion

查看:198
本文介绍了协变量返回类型和类型转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

s-> duplicate()返回 Box * 类型的对象,使用 Box * 初始化它时出错。它看起来像被转换回 Shape * 。如果将它转换回基类指针,则具有协变返回类型的意义是什么?:

  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();
}

错误:

  main.cpp:22:12:error:无法初始化类型为Shape *的类型为Box *的变量
Box * b = s-> ;重复();
^ ~~~~~~~~~~~~~~~
1错误生成。


解决方案

虽然重复 被调用(通过虚拟分派),虽然 Box :: duplicate > override Shape :: duplicate (covariantly),虽然 Box :: duplicate 返回一个 Box * ,你仍然会得到一个 Shape * ,因为这是函数的原始返回类型



C ++无法动态选择类型,因此这是最好的选择。您的 Box * 将在框中自动转换为 Shape * :duplicate 。正如Barry所说,它仍然需要在编译时编译,并且在编译时我们知道的是它返回一个 Shape *



然后,为了使它成为一个 Box * ,你需要显式强制转换(使用 static_cast


code> dynamic_cast [C ++ 11:10.3 / 7]: 覆盖函数的返回类型应与覆盖函数的返回类型相同或与函数类的协变量 [..]



[C ++ 11:10.3 / 8]:如果 D :: f 的返回类型与 B :: f 的返回类型不同, D :: f 在声明的时候完成 D :: f D 类类型。 当覆盖函数被调用作为重写函数的最终覆盖时,其结果将转换为由(静态选择的)覆盖函数(5.2.2)返回的类型。 [..]


在标准文本中, $ b

s->duplicate() returns an object of type Box*, but I'm getting an error initializing it with Box*. It looks like it's being converted back to Shape*. What is the point of having covariant return types if it's converted back to the base class pointer?:

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();
}

Error:

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.

解决方案

Although your Box::duplicate is being invoked (via virtual dispatch), and although Box::duplicate does override Shape::duplicate (covariantly), and although Box::duplicate does return a Box*, you'll still get a Shape* because that's the "original" return type of the function you're calling.

C++ is not able to dynamically select types, so this is the best it can do. Your Box* is being automatically converted to a Shape* on the way out of Box::duplicate. As Barry said, "it still has to compile at compile time, and at compile time all we know is that it returns a Shape*".

Then, to make it into a Box* again, you need to explicitly cast it (using static_cast or dynamic_cast) because no implicit down-conversion exists.

[C++11: 10.3/7]: The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. [..]

[C++11: 10.3/8]: If the return type of D::f differs from the return type of B::f, the class type in the return type of D::f shall be complete at the point of declaration of D::f or shall be the class type D. When the overriding function is called as the final overrider of the overridden function, its result is converted to the type returned by the (statically chosen) overridden function (5.2.2). [..]

In the standard text, a pertinent example follows.

这篇关于协变量返回类型和类型转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆