你应该static_cast
。在撤消隐式转换的情况下使用。static_cast
但是,在这种特殊情况下,没有区别,因为您是从void*
. 但一般来说,reinterpret_cast
两个对象指针之间的 ing 定义为(§5.2.10/7):
对象指针可以显式转换为不同类型的对象指针。当v
“pointer to T1
”类型的纯右值转换为“pointer to cv T2
”类型时,结果是static_cast<cv T2*>(static_cast<cv void*>(v))
如果T1
和T2
都是标准布局类型并且 的对齐要求T2
不比 的更严格T1
,或者任何一个类型都是void
。将“pointer to”类型的纯右值转换为“pointer to T1
”类型T2
(其中T1
和T2
是对象类型,其中 的对齐要求T2
不比 的 更严格T1
)并返回其原始类型会产生原始指针值。未指定任何其他此类指针转换的结果。
强调我的。既然T1
对你来说已经是void*
,那么对void*
in的强制转换reinterpret_cast
什么也不做。这通常不是真的,这就是Drew Dormann 所说的:
#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);
}
输出:
00CBFD5B
00CBFD5B
00CBFD5C
(请注意,因为y
实际上并不指向 a derived
,所以使用它是未定义的行为。)
在这里,reinterpret_cast
提出了一个不同的值,因为它通过void*
. 这就是为什么你应该static_cast
在可以和reinterpret_cast
必须的时候使用。