c – 为什么在这里使用static_cast而不是reinterpret_cast很重要?

前端之家收集整理的这篇文章主要介绍了c – 为什么在这里使用static_cast而不是reinterpret_cast很重要?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
At a reply of a blog post of Raymond Chen,

提问者指出

Raymond,I believe the C++ example is not correct since the position
of the base class subobject in the derived class is unspecified
according to ISO C++ 2003 Standard (10-3,page 168),and you assume
that the base class subobject is always at the beginning. The C
example would be fine in C++ too,so I’d stick with it.

雷蒙德回答

[The code does not make this assumption. That’s why it’s important to
use static_cast instead of reinterpret_cast. Try it: Add a virtual
method to OVERLAPPED (so a vtable goes in front) and observe what the
compiler does. -Raymond]

看完他的意见后,我可以猜到.在示例中使用static_cast很好,但reinterpret_cast不是.因为reinterpret_cast不转换vtable.我明白了吗?
虽然,如果我使用C风格的演员(不是reinterpret_cast),那也可能会出错?

我重读了更有效的C的演员说明,以了解这一点.但是没有答案.

解决方法

Using static_cast is fine at the example but reinterpret_cast is not. Because reinterpret_cast is not convert vtable.

不,问题是reinterpret_cast完全忘记了遗产.它将简单地返回相同的地址not1.但static_cast知道你正在执行一个downcast:即从基类转换为派生类.既然知道这两种类型,所以相应地调整地址,即做正确的事情.

假设我们的实现规定了假设的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

Though,if I use C-Style cast at there(not reinterpret_cast),could it also go wrong?

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++相关文章