我应该使用它还是static_cast <void*> then static_cast <myType*>以避免reinterpret_cast?

odi*_*erd 6 c++ casting static-cast reinterpret-cast

我见过人们建议使用static_cast<SomeType*>(static_cast<void*>(p))而不是重新解释铸造.

我不明白为什么这样更好,有人可以解释一下吗?

为了论证,这里是一个需要reinterpret_cast的示例场景:

DWORD lpNumberOfBytes;
ULONG_PTR lpCompletionKey;
LPOVERLAPPED lpOverlapped;
GetQueuedCompletionStatus(myHandle, &lpNumberOfBytes, &lpCompletionKey, &lpOverlapped, 0);
if(lpCompletionKey == myCustomHandlerKey){
    auto myObject = reinterpret_cast<MyObject*>(lpOverlapped);  //i know this is really a MyObject
}
Run Code Online (Sandbox Code Playgroud)

这是我听到的建议:

auto myObject = static_cast<MyObject*>(static_cast<void*>(lpOverlapped));
Run Code Online (Sandbox Code Playgroud)

编辑:我原来开始提问在评论部分"asdf"建议在这里使用static_cast而不是reinterpret_cast http://blogs.msdn.com/b/vcblog/archive/2014/02/04/challenge-vulnerable-code.aspx 但回想起来,我的问题来自那里是无关紧要的.

Kon*_*lph 7

§5.2.10描述了reinterpret_cast可以执行的合法映射,并指定"不能执行其他转换".

与您的示例相关的转换是/ 7:

指向对象的指针可以显式转换为指向不同对象类型的指针.当prvalue v类型的"指针T1"被转换为类型"指针CV T2 ",结果是如果两个是标准布局类型...和的对准要求并不比那些更严格.[强调我的]static_cast<cv T2*>(static_cast<cv void*>(v)) T1T2T2T1

任何其他指向对象类型的指针的转换结果是"未指定".1

这是两个原因,一个reinterpret_cast是危险的:它的转换只适用于指针的一个子集的对象类型明确,和编译器通常提供约偶然误操作诊断.

第二个原因是编译器甚至不检查您尝试执行的映射是否合法,以及将执行多个(语义上完全不同的)映射中的哪一个.

最好能够明确告诉编译器(和读者),其预期的转换是要执行.也就是说,asdf的评论并不完全正确,因为并非您可能想要通过的所有转换reinterpret_cast都等同于使用static_cast<void*>后跟a static_cast到目标类型.


1旁白:简而言之(略微简化),"标准布局类型"是一种类型(或类型数组),它没有虚函数或混合成员可见性,其所有成员和基础也是标准布局.类型的对齐是对它可能位于的存储器中的地址的限制.例如,许多机器要求doubles在可被8整除的地址处对齐.