[英]Why would I use dynamic_cast to cast TO a void *?
所以我正在阅读来自 "void *" 的 dynamic_cast的答案,虽然你不能从void *
转换为T *
一些响应指出可以将T *
转换为void *
,但不要没有任何迹象表明你为什么要这样做。
这只是可能的一些琐事,还是有可能有意义? 我考虑过可能是为了可读性或明确表示我们正在转换为void *
,但考虑到dynamic_cast
的目的,它不太适合我。
就此而言,除了让T *
void *
隐式变为void *
之外,还有什么理由可以做任何事情吗? 我已经看到 C 风格的转换为void *
不时用于这个目的,我认为只是明确的(假设我们没有做一些不寻常的事情,比如将int
转换为指针或其他东西)。
首先,当使用dynamic_cast<void*>(x)
您会得到一个指向最派生对象的第一个字节的指针。 只要x
的静态类型是多态的。
这在少数场景中很有用,其中地址用作对象标识:
当然,这当然不是日常使用,但在 C++ 中,内存地址是对象的事实上的标识符,因此从继承层次结构的任何部分访问它的机制对于那些少数极端情况肯定是有用的。
这是有目的的,有点。 在允许它的规范部分中暗示了它。 来自 N3337,第 5.2.7 节,第 7 段:
如果 T 是“指向 cv void 的指针”,则结果是指向 v 指向的最派生对象的指针。
所以dynamic_cast<void*>(...)
实际上是static_cast<void*>(dynamic_cast<MostDerivedType*>(...))
简写。 这将是有用的......有点。
使其有用的困难在于您不一定知道MostDerivedType
是什么。 毕竟,每个表达式都可能不同。 因此,一旦将其作为void*
,您就不一定有办法安全地将其恢复。 如果您对MostDerivedType
进行猜测并且只是static_cast
它,并且您错了,那么您就处于未定义的行为领域。 而如果您对该类型执行dynamic_cast
(然后static_cast
为void*
),如果它不是该类型,它至少会返回 NULL 。
所以不,我会说它不是很有用。 如果您想生活在 C++ 的边界内并且不依赖于潜在的未定义行为,则不是。
它在为运算符new和delete实现包装器时很有用。 问题是操作符delete允许我们使用指向多态对象基址的指针来释放内存。 在这种情况下,包装器不知道哪个对象真正在那里被释放(在包装器之前分配的所有对象中)。 所以我们使用dynamic_cast< void * >()作为对象的唯一标识 - 它转换为多态对象的最派生类型。 这允许我们跟踪当前通过此包装器分配的所有对象。 这种包装器可用于内存分配跟踪和批量释放。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.