c – 我应该使用它还是static_cast然后使用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
}

这是我听到的建议:

auto myObject = static_cast<MyObject*>(static_cast<void*>(lpOverlapped));

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

解决方法

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

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

A pointer to an object can be explicitly converted to a pointer to a different object type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”,the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types … and the alignment requirements of T2 are no stricter than those of T1. [emphasis mine]

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

这是reinterpret_cast危险的两个原因之一:它的转换仅为指向对象类型的指针子集定义良好,编译器通常不提供有关意外误用的诊断.

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

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

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

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...