来自“void *”的dynamic_cast
根据 this,void*
有没有 RTTI 信息,因此从 void*
进行转换是不合法的,但它是有意义的。
如果我没记错的话,来自 void*
的 dynamic_cast
正在 gcc 上运行。
您能澄清一下这个问题吗?
According to this, void*
has no RTTI information, therefore casting from void*
is not legal and it make sense.
If I remember correctly, dynamic_cast
from void*
was working on gcc.
Can you please clarify the issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
dynamic_cast
仅适用于多态类型,即包含虚函数的类。在 gcc 中,您可以
dynamic_cast
tovoid*
但不能 from:dynamic_cast
works only on polymorphic types, i.e. classes containing virtual functions.In gcc you can
dynamic_cast
tovoid*
but not from:在
5.2.7 - 动态转换 [expr.dynamic.cast]
中,它表示对于dynamic_cast(v)
:T
是指针类型,v
应是指向完整类类型的指针的右值T
是引用类型,v
应是以下的左值一个完整的类类型(感谢usta对我遗漏的评论)...
v
应该是一个指向多态类型的指针或多态类型的左值所以,不,一个
(void* )
不允许 值。让我们考虑一下您的请求可能意味着什么:假设您有一个真正指向
Derived1*
的指针,但代码dynamic_cast
-ing 只知道它是一个无效*
。假设您尝试将其转换为Derived2*
,其中两个派生类都有一个共同的基类。从表面上看,您可能认为所有指针都指向同一个 Base 对象,该对象将包含指向相关虚拟调度表和 RTTI 的指针,因此所有内容都可以挂在一起。但是,请考虑派生类可能有多个基类,因此所需的Base
类子对象可能不是Derived*
所使用的子对象 - 仅可作为void*
- 正在指向。这是行不通的。结论:编译器需要知道这些类型,以便它可以根据涉及的类型对指针进行一些调整。(一些答案谈到需要将您要转换的指针转换为具有虚函数的多态类型。这都是有效的,但有点误导。正如您在上面所看到的,即使
void*< /code> 是这样一种类型,如果没有完整的类型信息,它仍然无法可靠地工作,因为真正的问题是
void*
可能指向派生对象的开头,而您需要指向派生类型的基类子对象的指针。)In
5.2.7 - Dynamic cast [expr.dynamic.cast]
it says that fordynamic_cast<T>(v)
:T
is a pointer type,v
shall be an rvalue of a pointer to complete class typeT
is a reference type,v
shall be an lvalue of a complete class type (thanks usta for commenting on my missing this)...
v
shall be a pointer to or an lvalue of a polymorphic typeSo, no, a
(void*)
value is not allowed.Let's think about what your request might mean: say you've got a pointer that's really to a
Derived1*
, but the codedynamic_cast
-ing only knows it's avoid*
. Let's say you're trying to cast it to aDerived2*
, where both derived classes have a common base. Superficially, you might think all the pointers would point to the sameBase
object, which would contain a pointer to the relevant virtual dispatch table and RTTI, so everything could hang together. But, consider that derived classes may have multiple base classes, and therefore the neededBase
class sub-object might not be the one to which theDerived*
- available only as avoid*
- is pointing. It wouldn't work. Conclusion: the compiler needs to know these types so it can perform some adjustment to the pointers based on the types involved.(Some answers talk about the need for the pointer you're casting from to be of a polymorphic type, having virtual functions. That's all valid, but a bit misleading. As you can see above, even if the
void*
is to such a type it still wouldn't work reliably without the full type information, as the real problem is thatvoid*
is presumably pointing to the start of the derived object, whereas you need a pointer to the base class sub-object from which the cast-to type derives.)确实,不能对
void*
进行dynamically_cast
编辑。你可能记错了。
使用 g++ 4.5 和以下代码
我收到以下错误:
It is true that
void*
can't bedynamically_cast
ed from.You are probably mis-remembering.
With g++ 4.5 and the following code
I get the following error:
为了补充托尼的好答案,这个小代码片段出于某种原因对我有帮助。首先,我们建立一个简单的层次结构。然后,我们看看
dynamic_cast
是否能够在static_cast
中“生存”。在这个实验之前,我认为“运行时类型信息就在那里,动态转换应该弄清楚”。现在我意识到“dynamic_cast
必须根据编译器知道的一些表来查找它的信息,所以它不可能有什么神奇的力量。”To add to Tony's nice answer, this little code snippet helps me for some reason. First, we establish a simple hierarchy. Then, we see if
dynamic_cast
can "survive" astatic_cast
. Before this experiment I thought "the run time type information is there, dynamic cast should figure it out." Now I realize "dynamic_cast
must have to look up its information based on some tables the compiler is aware of, so it can't have some magical power."我猜您与
dynamic_cast
tovoid*
混淆了。这是合法的,并且获得指向最派生类对象的指针。dynamic_cast
fromvoid*
是非法的 - 所转换的类型必须是多态的 - 至少包含一个虚拟函数(虚拟析构函数也计算在内)。I guess you confuse with
dynamic_cast
tovoid*
. That is legal and obtains the pointer to the most derived class object.dynamic_cast
fromvoid*
is illegal - the type casted from must be polymorphic - contain at least one virtual function (virtual destructor counts too).您可以将指向多态类型的指针强制转换为
void *
,但反之则不然。You can cast a pointer to polymorphic type to
void *
, but not vice versa.