我的老师不像其他人那样进行类型转换。有谁知道他在做什么?
My teacher is not type-casting the same way as everyone else. Does anyone know what he is doing?
我的老师在我们的一个铸造示例中包含了以下几行。 c
是 class Circle
的对象,它继承自 class Point
。在寻找 "Can I cast an object of class Point
to type 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"
这是一个 C 风格的转换,如果可用,将使用 "c.operator Point()",否则它的行为与 "reintrepret_cast(c)"
相同
(Point)c
被称为“C 风格”演员表。这基本上可以被认为是一种蛮力转换,它会尽其所能使转换成功。这意味着它最终可能导致 static_cast
和 const_cast
甚至 reinterpret_cast
.
When the C-style cast expression is encountered, the compiler attempts to interpret it as the following cast expressions, in this order:
- const_cast
- static_cast
- static_cast 后跟 const_cast
- reinterpret_cast
- reinterpret_cast 后跟 const_cast
来源:https://en.cppreference.com/w/cpp/language/explicit_cast
来自 Stroustrup 本人:
Explicit type conversions (often called casts to remind you that they are used to prop up something broken) are best avoided.
和
C-style casts should have been deprecated in favor of named casts.
Stroustrup, Bjarne。 C++ 之旅(C++ 深入系列)(Kindle 位置 7134)。培生教育。 Kindle 版。
所以推荐命名转换。在实践中,我仍然会遇到使用 C 风格转换的专业代码,因为它使代码更简洁和可读,并且——如果你知道你在做什么——通常在它使用的地方等同于 static_cast
。对于它的价值,我认为如果出于这些原因在使它 明显 的上下文中使用 C 样式转换是可以的,它将导致 static_cast
,并且 Stroustrup 即将到来从过度面向对象的角度来看,他对演员表普遍不屑一顾。但是你应该更喜欢命名转换。
您的老师可能正在使用 C 风格的转换作为一种看起来不那么可怕的转换介绍。
到目前为止的答案并未涵盖 (Point) c;
的实际作用。假设 Circle
没有明确定义 operator Point
:
这与static_cast<Point>(c)
相同。它创建一个临时 Point
对象,该对象由 Point
的复制构造函数初始化,并以 c
作为参数。这是有效的,因为基础 class 复制构造函数,无论好坏,都可以绑定到派生对象。
明确地说,它不是对 Circle
的 Point
部分的任何形式的引用。它正在复制 Circle
的 Point
部分。这称为切片。它丢失了所有 "Circle" 部分信息。
我建议不要这样做。如果没有转换,代码会更好。我想也许 Point
和 Circle
都定义了 operator<<
重载,他想明确地 select Point
一个;在这种情况下,您应该使用 static_cast<Point&>(c)
或等效的 (Point&)c
来查看圆而不是对其进行切片。
注意。首先从 Point 派生 Circle 也是可疑的;继承应表示 "is-a" 关系(而不是 "has-a");但是圆不是点。
进一步阅读:What is object slicing?
我的老师在我们的一个铸造示例中包含了以下几行。 c
是 class Circle
的对象,它继承自 class Point
。在寻找 "Can I cast an object of class Point
to type 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"
这是一个 C 风格的转换,如果可用,将使用 "c.operator Point()",否则它的行为与 "reintrepret_cast(c)"
相同(Point)c
被称为“C 风格”演员表。这基本上可以被认为是一种蛮力转换,它会尽其所能使转换成功。这意味着它最终可能导致 static_cast
和 const_cast
甚至 reinterpret_cast
.
When the C-style cast expression is encountered, the compiler attempts to interpret it as the following cast expressions, in this order:
- const_cast
- static_cast
- static_cast 后跟 const_cast
- reinterpret_cast
- reinterpret_cast 后跟 const_cast
来源:https://en.cppreference.com/w/cpp/language/explicit_cast
来自 Stroustrup 本人:
Explicit type conversions (often called casts to remind you that they are used to prop up something broken) are best avoided.
和
C-style casts should have been deprecated in favor of named casts.
Stroustrup, Bjarne。 C++ 之旅(C++ 深入系列)(Kindle 位置 7134)。培生教育。 Kindle 版。
所以推荐命名转换。在实践中,我仍然会遇到使用 C 风格转换的专业代码,因为它使代码更简洁和可读,并且——如果你知道你在做什么——通常在它使用的地方等同于 static_cast
。对于它的价值,我认为如果出于这些原因在使它 明显 的上下文中使用 C 样式转换是可以的,它将导致 static_cast
,并且 Stroustrup 即将到来从过度面向对象的角度来看,他对演员表普遍不屑一顾。但是你应该更喜欢命名转换。
您的老师可能正在使用 C 风格的转换作为一种看起来不那么可怕的转换介绍。
到目前为止的答案并未涵盖 (Point) c;
的实际作用。假设 Circle
没有明确定义 operator Point
:
这与static_cast<Point>(c)
相同。它创建一个临时 Point
对象,该对象由 Point
的复制构造函数初始化,并以 c
作为参数。这是有效的,因为基础 class 复制构造函数,无论好坏,都可以绑定到派生对象。
明确地说,它不是对 Circle
的 Point
部分的任何形式的引用。它正在复制 Circle
的 Point
部分。这称为切片。它丢失了所有 "Circle" 部分信息。
我建议不要这样做。如果没有转换,代码会更好。我想也许 Point
和 Circle
都定义了 operator<<
重载,他想明确地 select Point
一个;在这种情况下,您应该使用 static_cast<Point&>(c)
或等效的 (Point&)c
来查看圆而不是对其进行切片。
注意。首先从 Point 派生 Circle 也是可疑的;继承应表示 "is-a" 关系(而不是 "has-a");但是圆不是点。
进一步阅读:What is object slicing?