gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 16:29:57 25 4
gpt4 key购买 nike

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.

Raymond回复了

[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 不是convert vtable。我的理解正确吗?
不过,如果我在那里使用 C-Style cast(不是 reinterpret_cast),它也会出错吗?

我重新阅读了 More Effective C++ 的转换解释以了解这一点。但对此没有任何答复。

最佳答案

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

不,问题在于 reinterpret_cast 完全忽略了继承。它只会返回不变的相同地址1。但是 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

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

C 风格转换被定义为以下第一个成功的转换:

  1. const_cast
  2. static_cast
  3. static_cast,然后是 const_cast
  4. 重新解释_cast
  5. reinterpret_cast,然后是const_cast

如您所见,在 reinterpret_cast 之前尝试了 static_cast,因此在这种情况下,C 风格的强制转换也会做正确的事情。


More info


1不保证。对于 reinterpret_cast 上发生的事情几乎没有任何保证。我所知道的所有实现都会简单地给出相同的地址。

关于c++ - 为什么在这里使用 static_cast 而不是 reinterpret_cast 很重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9138730/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com