C++ 转换指针类型的正确方法

C++ 转换指针类型的正确方法,c++,pointers,casting,reinterpret-cast,static-cast,C++,Pointers,Casting,Reinterpret Cast,Static Cast,考虑到(以及以下事实): BYTE*pbNext=reinterpret\u cast( VirtualAlloc(NULL、cbAlloc、MEM_COMMIT、PAGE_READWRITE)); 为什么选择了reinterpret\u cast而不是static\u cast 我曾经认为,reinterpret\u cast可以用于向整数类型和从整数类型转换指针(例如,DWORD\u PTR),但是从void*转换为BYTE*,不是吗静态\u cast可以吗 在这种特殊情况下是否存在任何(

考虑到(以及以下事实):

BYTE*pbNext=reinterpret\u cast(
VirtualAlloc(NULL、cbAlloc、MEM_COMMIT、PAGE_READWRITE));
为什么选择了
reinterpret\u cast
而不是
static\u cast

我曾经认为,
reinterpret\u cast
可以用于向整数类型和从整数类型转换指针(例如,
DWORD\u PTR
),但是从
void*
转换为
BYTE*
,不是吗
静态\u cast
可以吗

在这种特殊情况下是否存在任何(细微的?)差异,或者它们都是有效的指针强制转换


C++标准是否对该情况有偏好,建议用一种方式代替另一种方式?< < P > > P > >强转换>指向基本类型的可转换指针< /强>两种转换具有相同的含义;所以您认为

静态\u cast
是正确的

在某些指针类型之间转换时,指针中的特定内存地址可能需要更改

这就是两种类型的不同之处<代码>静态投影将进行适当的调整<代码>重新解释强制转换将不会


因此,在指针类型之间进行
static\u cast
是一个很好的通用规则,除非您知道需要
reinterpret\u cast

使用
static\u cast
void*
投射指针可以保证保留地址

另一方面,
reinterpret\u cast
可以保证,如果将指针从一种类型转换到另一种类型,并返回到原始类型,则地址将保留


虽然在大多数实现中,使用这两种方法都会得到相同的结果,但是应该首选
static\u cast

对于
C++11
我记得,使用
reinterpret\u cast
for
void*
有一个定义良好的行为。在此之前,这种行为是被禁止的

It is not permitted to use reinterpret_cast to convert between pointers to object type and pointers to void.
拟议决议(2010年8月):

将5.2.10【解释性重新解释】第7段更改如下:

对象指针可以显式转换为 一种不同的类型。当“指向T1的指针”类型的PRV值为 转换为“指向cv T2的指针”类型,如果T1和T2都是标准布局,则结果为static_cast(static_cast(v)) 类型(3.9[基本类型])和T2的对准要求不适用 比T1更严格,或者任一类型无效

将“指针到T1”类型的PR值转换为“指针到T1”类型 T2“(其中T1和T2是对象类型,路线 T2的要求并不比T1)的要求更严格,并返回到its 原始类型生成原始指针值。任何结果 未指定其他此类指针转换

更多信息


感谢您的链接。

您应该
static\u cast
在撤消隐式转换的情况下使用
static\u cast

但是,在这种特殊情况下,没有区别,因为您正在从
void*
转换。但通常,两个对象指针之间的重新解释(§5.2.10/7):

对象指针可以显式转换为不同类型的对象指针。当“指针指向
T1
”类型的prvalue
v
转换为“指针指向cv
T2
”类型时,结果为
static\u cast(static\u cast(v))
如果
T1
T2
都是标准布局类型,并且
T2
的对齐要求不比
T1
严格,或者如果其中任何一种类型都是
void
。将“指针指向
T1
”类型的PR值转换为“指针指向
T2
”类型(其中
T1
T2
是对象类型,其中
T2
的对齐要求不比
T1
的对齐要求更严格),然后返回到其原始类型,即可生成原始指针值。任何其他此类指针转换的结果均不明确

我的。由于您的
T1
void*
,因此在
reinterpret\u cast
中对
void*
的强制转换不起任何作用。一般来说,情况并非如此,这就是:

#包括
模板
无效打印_指针(常数可变T*ptr)
{
//这是标准中的监督所需要的

std::cout首先,我不会假设微软开发人员遵循“事实上的良好实践”。
static\u cast
在这里很好。
static\u cast
应该是首选,但有些人更喜欢
reinterpret\u cast
,因为名称显示了您正在做什么(您正在重新解释位模式)。(无论如何,+1,享受你的
好问题
徽章!)这是一个关于重新解释强制转换的例子,它在C++11之前实际上是被禁止的。很好的说明!关于
void*
转换-我有一个烦人的回忆,特别是对于转换到
void*
,标准允许
reinterpret\u cast
来更改值。而且只有循环转换
X*
void*
X*
保证保留地址。这不正确吗?@DrewDormann:我不确定我是否遵循,你指的是哪一行?对于
重新解释
,所有带有
void*
的情况(作为源类型或目标类型)请仔细阅读我引用的条款,从这一点来看,唯一相关的是
static\u cast
w.r.t.
void*
。希望澄清。@GManNickG我可以知道你对这个问题的看法吗?根据这里的答案,我认为在这里使用2 static更安全,但如果我错了,你能纠正我吗。
It is not permitted to use reinterpret_cast to convert between pointers to object type and pointers to void.
#include <iostream>

template <typename T>
void print_pointer(const volatile T* ptr)
{
    // this is needed by oversight in the standard
    std::cout << static_cast<void*>(const_cast<T*>(ptr)) << std::endl;
}

struct base_a {};
struct base_b {};
struct derived : base_a, base_b {};

int main()
{
    derived d;

    base_b* b = &d; // implicit cast

    // undo implicit cast with static_cast
    derived* x = static_cast<derived*>(b);

    // reinterpret the value with reinterpret_cast
    derived* y = reinterpret_cast<derived*>(b);

    print_pointer(&d);
    print_pointer(x);
    print_pointer(y);
}