协变量返回类型和类型转换 [英] Covariant return type and type conversion
问题描述
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 *
将在框中自动转换为
。正如Barry所说,它仍然需要在编译时编译,并且在编译时我们知道的是它返回一个 Shape *
:duplicate 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 ofD::f
differs from the return type ofB::f
, the class type in the return type ofD::f
shall be complete at the point of declaration ofD::f
or shall be the class typeD
. 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屋!