在示例中使用static_cast很好,但reinterpret_cast不是。因为reinterpret_cast不是转换vtable。
不,问题是reinterpret_cast
完全遗忘了继承。它将简单地返回相同的地址。但static_cast
知道您正在执行向下转换:即从基类转换为派生类。既然它知道这两种类型,就相应地调整地址,即做正确的事情。
让我们假装我们实施勾画出假想OVERLAPPEDEX
类,它具有这样的虚函数:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr
指针我们给出指向OVERLAPPED
子对象。 reinterpret_cast
不会改变这一点。它只会改变类型。显然,通过这个地址访问OVERLAPPEDEX
类会很容易造成严重破坏,因为它的子对象的位置现在都是错误的!
what we believe we have when we access OVERLAPPEDEX through the pointer
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------+-----+------+-----------+------+------+------+
| vptr | OVERLAPPED | AssociatedClient | ClientState | <- what we actually have
+------+------------+------------------+-------------+
^
|
ptr
static_cast
知道,要转换OVERLAPPED*
到OVERLAPPEDEX*
它必须调整的地址,并做正确的事:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr after static_cast
不过,如果我使用C-风格投在那里(不是reinterpret_cast),它可能会出错吗?
A C样式转换被定义为成功以下的第一个:
const_cast
static_cast
static_cast
,然后const_cast
reinterpret_cast
reinterpret_cast
,然后const_cast
正如你所看到的,static_cast
reinterpret_cast
之前尝试过,所以在这种情况下,C样式转换也将做正确的事。
More info
不能保证。关于reinterpret_cast
发生的情况几乎没有什么保证。我所知道的所有实现都将简单地给出相同的地址。
我对C++一点也不熟悉,但我的理解是,“重新解释强制转换”意味着在C中'*(destination_type *)&'意味着什么。推测“静态强制转换”实际上需要类关系帐户,并允许编译器进行非平凡的转换工作。 – 2012-02-04 05:51:41