使用 static_cast 然后 dynamic_cast

Using static_cast and then dynamic_cast

我正在处理一个特殊情况,我不能直接使用 dynamic_cast,因为对象是 void*。是先使用 static_cast 然后使用 dynamic_cast(在 static_cast 的结果上)不好的做法吗?有错吗?

这是我所说的示例:

MyClass* CastVoidPtr(void* pVoidPtr)
{
    // casting it to MyClass so we could use dynamic_cast
    MyClass* pTemp = static_cast<MyClass*>(pVoidPtr);

    // returning the actual result that will make sure that we have a MyClass object or a nullptr
    return dynamic_cast<MyClass*>(pTemp);
}

这取决于指针是如何成为 void* 的。如果它从与被转换为相同的类型转换为 void*(这里是 MyClass*),那么是的,这个转换很好并且按预期工作;

来自cppreference on static_cast

A prvalue of type pointer to void (possibly cv-qualified) can be converted to pointer to any type. If the value of the original pointer satisfies the alignment requirement of the target type, then the resulting pointer value is unchanged, otherwise it is unspecified. Conversion of any pointer to pointer to void and back to pointer to the original (or more cv-qualified) type preserves its original value.

以这种方式使用static_cast本质上是对编译器说"I know it is this type - trust me",并且编译器有义务。

dynamic_cast 可以在这之后进行计算。它通常用于转换为更派生的类型。在这里,您正在转换为相同的类型 - 它没有做任何特别有用的事情。如果该类型是更派生的类型(例如 MySpecialisedClass),那么就可以了。


按照目前的情况,函数可以简化为:

MyClass* CastVoidPtr(void* pVoidPtr)
{
    return static_cast<MyClass*>(pVoidPtr);
}

或者简单地使用裸体 static_cast<>


旁注;这里值得一提的是 reinterpret_cast has similar functionality;

Any pointer to object of type T1 can be converted to pointer to object of another type cv T2. This is exactly equivalent to static_cast<cv T2*>(static_cast<cv void*>(expression)) (which implies that if T2's alignment requirement is not stricter than T1's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules ...