为什么 dynamic_cast 可以用于非多态类型的向上转换?
Why dynamic_cast is ok to use for upcast for non polymorphic types?
参见here:
dynamic_cast can only be used with pointers and references to classes
(or with void*). Its purpose is to ensure that the result of the type
conversion points to a valid complete object of the destination
pointer type.
This naturally includes pointer upcast (converting from
pointer-to-derived to pointer-to-base), in the same way as allowed as
an implicit conversion.
But dynamic_cast can also downcast (convert from pointer-to-base to
pointer-to-derived) polymorphic classes (those with virtual members)
if -and only if- the pointed object is a valid complete object of the
target type.
为什么 dynamic_cast 可以用于非多态类型的向上转换,但不能再次用于非多态类型的向下转换?
可以在不知道所指向对象的确切类型的情况下将派生类型指针转换为基类型指针,因为派生类型始终是基本类型。也就是说,转换仅取决于 static 信息。所以dynamic_cast
那个方向总是没问题的,因为总能做到。
使用 dynamic_cast
转换另一种方式需要知道所指向对象的实际类型,因为没有该信息就无法知道转换是否有效。例如:
Base* bp = get_base();
Derived* dp = dynamic_cast<Derived*>(bp);
在这种情况下,如果 bp
实际上指向 Base
类型的对象,则转换无效;如果它指向 Derived
类型的对象或从 Derived
派生的类型,则转换没问题。
为了在运行时确定对象的确切类型,支持代码依赖于嵌入式类型信息,该信息只需要存在于多态类型中。这就是为什么 base-to-derived cast 需要多态类型的原因:它确保存在所需的信息。
诚然,该标准本可以使派生到基础的转换对于非多态类型无效,但这是一个 procrustean 限制;没有充分的理由禁止它。
参见here:
dynamic_cast can only be used with pointers and references to classes (or with void*). Its purpose is to ensure that the result of the type conversion points to a valid complete object of the destination pointer type.
This naturally includes pointer upcast (converting from pointer-to-derived to pointer-to-base), in the same way as allowed as an implicit conversion.
But dynamic_cast can also downcast (convert from pointer-to-base to pointer-to-derived) polymorphic classes (those with virtual members) if -and only if- the pointed object is a valid complete object of the target type.
为什么 dynamic_cast 可以用于非多态类型的向上转换,但不能再次用于非多态类型的向下转换?
可以在不知道所指向对象的确切类型的情况下将派生类型指针转换为基类型指针,因为派生类型始终是基本类型。也就是说,转换仅取决于 static 信息。所以dynamic_cast
那个方向总是没问题的,因为总能做到。
使用 dynamic_cast
转换另一种方式需要知道所指向对象的实际类型,因为没有该信息就无法知道转换是否有效。例如:
Base* bp = get_base();
Derived* dp = dynamic_cast<Derived*>(bp);
在这种情况下,如果 bp
实际上指向 Base
类型的对象,则转换无效;如果它指向 Derived
类型的对象或从 Derived
派生的类型,则转换没问题。
为了在运行时确定对象的确切类型,支持代码依赖于嵌入式类型信息,该信息只需要存在于多态类型中。这就是为什么 base-to-derived cast 需要多态类型的原因:它确保存在所需的信息。
诚然,该标准本可以使派生到基础的转换对于非多态类型无效,但这是一个 procrustean 限制;没有充分的理由禁止它。