我的老师在我们的一个铸造示例中包含了以下几行。 c
是类Circle
的对象,它继承自类Point
。在我搜索问题的答案时,我可以将类Point
的对象转换为Circle
类型吗?"我发现他使用的语法与我曾经使用的每个网站不同。这些网站都使用static_cast
和dynamic_cast
语法。他不会在测试中使用static_cast和dynamic_cast,我只是想知道他在使用什么以及它是如何运作的。
另外,如果你能回答我是否可以将基础对象转换为派生类型,我非常感谢你。
output << "the center of the circle is at " << (Point) c;
// casting `Circle` object `c` with type `(Point)`, calls the first overloaded >stream insertion operator"
答案 0 :(得分:6)
(Point)c
被称为“C风格”演员。这基本上可以被认为是一个强力阵容,尽其所能使演员阵容成功。这意味着它最终可能导致static_cast
const_cast
甚至reinterpret_cast
。
来自https://anteru.net/blog/2007/12/18/200/:
使用(类型)变量语法进行C样式转换。有史以来最糟糕的发明。这将尝试按以下顺序执行以下转换:(另请参阅C ++标准,5.4 expr.cast第5段)
- 的const_cast
- 的static_cast
- static_cast后跟const_cast
- 的reinterpret_cast
- reinterpret_cast后跟const_cast
你认为这只是一个邪恶的演员阵容,事实上它是一个水弹!
来自Stroustrup本人:
最好避免显式类型转换(通常称为强制转换,以提醒您它们用于支撑破坏的东西)。
和
应该弃用C风格的强制转型,转而使用命名演员。
Stroustrup,Bjarne。 C ++之旅(C ++深度系列)(Kindle位置7134)。皮尔逊教育。 Kindle版。
所以建议使用命名演员表。在实践中,我仍然会遇到使用C风格演员表的专业代码,因为它使代码更加简洁和可读 - 如果你知道你在做什么 - 通常在它使用的地方相当于static_cast
。我觉得C风格的演员阵容如果因为这些原因而被用于显而易见 它会导致static_cast
,并且Stroustrup来自过度面向对象的观点在他一般不屑于铸造。但你应该更喜欢命名演员。
你的老师可能正在使用C风格的演员表作为一个不那么可怕的演员介绍。
答案 1 :(得分:3)
到目前为止,答案并没有涵盖(Point) c;
实际做的事情。假设Circle
没有明确定义operator Point
:
这与static_cast<Point>(c)
相同。它创建一个临时的Point
对象,由Point
的拷贝构造函数初始化,其中c
为参数。这是有效的,因为基类复制构造函数可以,无论好坏,都可以绑定到派生对象。
要清楚,它不是Point
Circle
部分的任何类型的引用。它正在复制Point
的{{1}}部分。这称为切片。它丢失了信息的所有“圆圈”部分。
我建议不要这样做。如果没有演员阵容,代码会更好。我想也许Circle
和operator<<
都有定义Point
重载,他想明确选择Circle
一个;在这种情况下,您应该使用Point
或等效的static_cast<Point&>(c)
来查看圆圈而不是切片。
NB。首先从Point派生Circle也是可疑的;继承应该代表“is-a”关系(而不是“has-a”);但是圆圈不是重点。
进一步阅读:What is object slicing?
答案 2 :(得分:-1)
这是一个C风格的演员,将使用&#34; c.operator Point()&#34;如果可用,否则它的行为与&#34; reintrepret_cast(c)&#34;
相同