C++ 我应该在将 void* 转换为任何内容时使用 static_cast 还是 reinterpret_cast

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/310451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:33:01  来源:igfitidea点击:

Should I use static_cast or reinterpret_cast when casting a void* to whatever

c++pointersstatic-castreinterpret-cast

提问by Andy

Both static_cast and reinterpret_cast seem to work fine for casting void* to another pointer type. Is there a good reason to favor one over the other?

static_cast 和 reinterpret_cast 似乎都可以很好地将 void* 转换为另一种指针类型。是否有充分的理由偏爱其中一个?

回答by Konrad Rudolph

Use static_cast: it is the narrowest cast that exactly describes what conversion is made here.

使用static_cast:它是最窄的强制转换,准确描述了此处进行的转换。

There's a misconception that using reinterpret_castwould be a better match because it means?“completely ignore type safety and just cast from A to B”.

有一种误解,认为 usingreinterpret_cast会更好匹配,因为它意味着?“完全忽略类型安全,只是从 A 转换到 B”。

However, this doesn't actually describe the effect of a reinterpret_cast. Rather, reinterpret_casthas a number of meanings, for all of which holds that “the mapping performed by reinterpret_castis implementation-defined.” [5.2.10.3]

但是,这实际上并没有描述reinterpret_cast. 相反,reinterpret_cast具有多种含义,因为所有这些含义都认为“执行的映射reinterpret_cast是实现定义的”。[5.2.10.3]

But in the particular case of casting from void*to T*the mapping is completely well-defined by the standard; namely, to assign a type to a typeless pointer without changing its address.

但是在特定情况下,从void*T*映射的转换完全由标准定义;即,将类型分配给无类型指针而不更改其地址。

This is a reason to prefer static_cast.

这是选择static_cast.

Additionally, and arguably more important, is the fact that every use of reinterpret_castis downright dangerous because it converts anything to anything else really (for pointers), while static_castis much more restrictive, thus providing a better level of protection. This has already saved me from bugs where I accidentally tried to coerce one pointer type into another.

此外,可以说更重要的是,每次使用reinterpret_cast都是彻头彻尾的危险,因为它实际上将任何东西转换为其他任何东西(对于指针),而static_cast限制性要大得多,从而提供了更好的保护级别。这已经使我避免了错误,因为我不小心试图将一种指针类型强制转换为另一种指针类型。

回答by Nick

This is a tough question. On the one hand, Konrad makes an excellent point about the spec definition for reinterpret_cast, although in practice it probably does the same thing. On the other hand, if you're casting between pointer types (as is fairly common when indexing in memory via a char*, for example), static_castwill generate a compiler error and you'll be forced to use reinterpret_castanyway.

这是一个棘手的问题。一方面,Konrad 对reinterpret_cast的规范定义提出了一个很好的观点,尽管在实践中它可能会做同样的事情。另一方面,如果您在指针类型之间进行转换(例如,通过 char* 在内存中进行索引时很常见),static_cast将生成编译器错误,并且无论如何您都将被迫使用reinterpret_cast

In practice I use reinterpret_castbecause it's more descriptive of the intent of the cast operation. You could certainly make a case for a different operator to designate pointer reinterprets only (which guaranteed the same address returned), but there isn't one in the standard.

在实践中,我使用reinterpret_cast因为它更能描述转换操作的意图。您当然可以为不同的运算符指定仅重新解释指针的情况(这保证返回相同的地址),但标准中没有。

回答by Pavel Radzivilovsky

I suggest using the weakest possible cast always.

我建议始终使用最弱的演员阵容。

reinterpret_castmay be used to cast a pointer to a float. The more structure-breaking the cast is, the more attention using it requires.

reinterpret_cast可用于将指针强制转换为 a float。铸件的结构破坏越多,使用它所需的注意力就越多。

In case of char*, I'd use c-style cast, until we have some reinterpret_pointer_cast, because it's weaker and nothing else is sufficient.

在 的情况下char*,我会使用 c 风格的强制转换,直到我们有一些reinterpret_pointer_cast,因为它更弱,没有其他足够的。

回答by Robert Gould

My personal preference is based on code literacy like this:

我个人的偏好是基于这样的代码素养:

void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();

or

或者

typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();

They both do the same in the end, but static_cast seems more appropriate in a middle-ware, app enviroment, while reinterpret cast seems more like something you'd see in a lower-level library IMHO.

他们最终都做同样的事情,但 static_cast 在中间件、应用程序环境中似乎更合适,而 reinterpret cast 似乎更像是你在较低级别的库中看到的恕我直言。