Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在这里使用静态转换而不是重新解释转换很重要?_C++_Pointers_Casting_Reinterpret Cast_Static Cast - Fatal编程技术网

C++ 为什么在这里使用静态转换而不是重新解释转换很重要?

C++ 为什么在这里使用静态转换而不是重新解释转换很重要?,c++,pointers,casting,reinterpret-cast,static-cast,C++,Pointers,Casting,Reinterpret Cast,Static Cast,, 一位提问者指出 雷蒙德回答 [代码没有做出这种假设。这就是为什么 使用静态转换而不是重新解释转换。请尝试:添加虚拟转换 方法重叠(使vtable位于前面)并观察 是的-雷蒙德] 看了他的评论,我可以猜出来。在本例中,使用static_cast是可以的,但是reinterpret_cast不是。因为reinterpret_cast不是convert vtable。我理解正确吗? 不过,如果我在那里使用C风格的cast(而不是reinterpret_cast),它也会出错吗 为了理解这一点,我

,

一位提问者指出

<雷蒙德,我相信C++的例子自从位置以来是不正确的。 未指定派生类中基类子对象的 按照ISO C++ 2003标准(10-3页,168页),你假设 基类子对象始终位于开头。C C++中的例子也很好,所以我会坚持下去。p> 雷蒙德回答

[代码没有做出这种假设。这就是为什么 使用静态转换而不是重新解释转换。请尝试:添加虚拟转换 方法重叠(使vtable位于前面)并观察 是的-雷蒙德]

看了他的评论,我可以猜出来。在本例中,使用static_cast是可以的,但是reinterpret_cast不是。因为reinterpret_cast不是convert vtable。我理解正确吗?
不过,如果我在那里使用C风格的cast(而不是reinterpret_cast),它也会出错吗

为了理解这一点,我重新阅读了更有效的C++的cast解释。但对此没有答案

在本例中,使用static_cast是可以的,但是reinterpret_cast不是。因为reinterpret_cast不是convert vtable

不,问题是,
reinterpret\u cast
完全忽略了继承。它只会返回相同的地址而不更改1。但是
static_cast
知道您正在执行向下转换:即从基类转换到派生类。因为它知道涉及的两种类型,所以会相应地调整地址,即做正确的事情

让我们假设我们的实现展示了一个假设的
OVERLAPPEDEX
类,该类具有如下虚拟函数:

+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
       ^
       |
      ptr
给我们的指针指向重叠的
子对象<代码>重新解释\u 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

不过,如果我在那里使用C风格的cast(而不是reinterpret_cast),它也会出错吗

C样式转换定义为以下第一个成功的转换:

  • const\u cast
  • static\u cast
  • static\u cast
    ,然后
    const\u cast
  • 重新解释演员阵容
  • 重新解释cast
    ,然后
    const\u cast
  • 如您所见,在
    重新解释\u cast
    之前会尝试
    静态\u cast
    ,因此在这种情况下,C样式的cast也会做正确的事情




    1不保证。对于
    重新解释cast
    时会发生什么,几乎没有什么保证。我知道的所有实现都会简单地给出相同的地址。< /P>我完全不懂C++,但是我的理解是“重新解释CAST”的意思是“代码> >(DestialSype类型)和在C.可能意味着“静态转换”。实际上,它考虑了类之间的关系,并允许编译器进行非平凡的转换工作。是的,我的
    convert vtable
    是一个非常奇怪的句子。顺便问一下,C风格的施法者也知道继承关系吗?也许不是。但我一直使用C风格的演员阵容,即使我使用C++。我认为它甚至在这个例子中起到了很好的作用。Benjamin我补充了一个关于C样式转换的解释,以及为什么它在这种情况下有效。不过我建议不要使用它们,因为选择哪种替代方案并不总是很清楚。C型机箱是一把非常钝的锤子。当然我会听从你的建议,因为我现在明白了。非常感谢。不过,您的C风格转换顺序是否标准化了?@Benjamin是的,该顺序是由标准指定的。还请注意,C风格转换可能存在一个问题:如果编译器无法确定存在继承结构(例如缺少头include),它将返回到
    reinterpret\u cast
    ,以同样的方式失败。这也是C型铸造危险的另一个原因。
     +------+------------+------------------+-------------+
     | vptr | OVERLAPPED | AssociatedClient | ClientState |
     +------+------------+------------------+-------------+
     ^
     |
    ptr after static_cast