我知道reinterpret_cast
主要用于进出char*
。
但我很惊讶地发现static_cast
可以对void*
做同样的事情。例如:
auto foo "hello world"s;
auto temp = static_cast<void*>(&foo);
auto bar = static_cast<string*>(temp);
使用reinterpret_cast
和char*
而非static_cast
和void*
可以获得什么?这与严格的别名问题有关吗?
答案 0 :(得分:0)
一般来说,static_cast
会投出任何两种类型,如果其中一种可以强制转换为另一种隐式。这包括算术强制转换,向下转换,向上转换以及来自void*
的转换。
也就是说,如果此演员表有效:
void foo(A a);
B b;
foo(b);
然后static_cast<B>(a)
和static_cast<A>(b)
都有效。
因为任何指针都可以隐式地转换为void*
,因此你的特殊行为。
reinterpret_cast
通过重新解释值的位模式来进行转换。正如你在问题中所说的那样,通常是在不相关的指针类型之间进行转换。
是的,您可以使用两个void*
通过static_cast
在不相关的指针类型之间进行转换:
B *b;
A *a1 = static_cast<A*>(b); //compiler error
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)!
但那是在歪曲规则。如果您确实需要,请使用reinterpret_cast
。
答案 1 :(得分:0)
您的问题实际上有两个部分:
static_cast
或reinterpret_cast
来处理指向对象的基础位模式的指针而不关心对象类型吗?reinterpret_cast
使用void*
或char*
来解决此基础位模式?
static_cast
:使用隐式转换和用户定义转换的组合在类型之间进行转换
在5.2.9 [expr.static.cast] 13中,标准实际上给出了一个例子:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
它利用隐式演员:
指向任何(可选的cv限定的)对象类型
T
的prvalue指针可以转换为prvalue指针(相同的cv-qualified)void
。结果指针表示内存中与原始指针值相同的位置。如果原始指针是空指针值,则结果是目标类型的空指针值。 *
然而,从T
类型的指针到char*
没有隐式转换。因此,实现该演员表的唯一方法是使用reinterpret_cast
。
在类型之间进行转换
reinterpret_cast
:通过重新解释基础位模式
因此,当您转换为void*
或char*
时,如果您希望使用基础位模式,那么在回答问题的 1 部分时,应该使用reinterpret_cast
,因为它的使用表示读者与基础位模式之间的转换。
接下来让我们将void*
与char*
进行比较。这两者之间的决定可能更依赖于应用程序。如果要使用基础位模式的标准库函数,只需使用函数接受的类型:
值得注意的是,C ++特定的库更喜欢char*
来指向内存。
由于指针here,出于兼容性原因,似乎保留了作为void*
的内存。因此,如果cstring
库函数不能在您的基础位模式上使用,请使用C ++特定库行为来回答您问题的 2 部分:首选{{ 1}}到char*
。