面试题:static_cast与reinterpret_cast在指针转换中的区别。

面试题:static_cast与reinterpret_cast在指针转换中的区别。

编码文章call10242025-05-21 12:35:173A+A-

面试题:既然static_cast也可以用于指针类型的转换,为什么还需要reinterpret_cast?


这个问题,看了网上的很多答案,其实都没有讲清楚,很多都是说下概念,举例也没有针对性。


static_cast适用于很多情况,我们这里就只说指针类型的转换(也不包括多态类型的指针,另外一篇文章有详细的讲解)


static_cast用于指针类型转换的时候,除了多态类型指针外有两种情况:

1:将 void* 转换为其他类型的指针。

2:同一个类型的不同实例之间进行转换。


而reinterpret_cast要做的恰恰是不同类型之间的转换,它允许我们将一个类型的指针转换为另一个类型的指针,即使它们的内部表示可能完全不同。


我们直接看代码:

#include <iostream>


class MyClass 
{
public:
    virtual ~MyClass() {}
    virtual void doSomething() { std::cout << "MyClass::doSomething()" << std::endl; }
};


class AnotherClass 
{
public:
    void doAnotherThing() { std::cout << "AnotherClass::doAnotherThing()" << std::endl; }
};


int main() 
{
    // 尝试转换两个不相关的类对象
    AnotherClass anotherObj;
    MyClass* Ptr = static_cast<MyClass*>(&anotherObj); // 编译错误 


    delete Ptr; // 释放内存


    return 0;
}

有两个类,MyClass和AnotherClass,这两个类是完全不同的类型,这个时候使用static_cast进行转换,编译直接报错。

错误 C2440 “static_cast”: 无法从“AnotherClass *”转换为“MyClass *” 0711


当把static_cast换成reinterpret_cast的时候,代码编译通过,但是在运行的时候发生了崩溃

    // 尝试转换两个不相关的类对象
    AnotherClass anotherObj;
    //MyClass* Ptr = static_cast<MyClass*>(&anotherObj); // 编译错误
    MyClass* Ptr = reinterpret_cast<MyClass*>(&anotherObj);  


    delete Ptr; // 释放内存

从这个例子可以看出


如果使用static_cast尝试将一个类型的指针直接转换为另一个不相关类型的指针,将会导致编译错误。这说明了static_cast是一种类型安全的转换方式。


换成reinterpret_cast编译通过,说明了reinterpret_cast 提供的是一种类型不安全的转换方式。而在运行时候崩溃,则告诉我们,reinterpret_cast应该谨慎使用,因为它可能会导致未定义行为


只有在确实需要进行低级别的类型转换时才使用 reinterpret_cast。比如将指针转换为整数再转换回去等操作,reinterpret_cast 将更有用。

#include <iostream>
int main() 
{
    // 使用 static_cast
    int val = 10;
    void* voidPtr = (void*)&val; 
    int* intPtr = static_cast<int*>(voidPtr); // 从 void* 到 int* 的类型安全转换


    // 使用 reinterpret_cast
    int value = 1024;
    void* voidPtr2 = reinterpret_cast<void*>(&value); // 将 int 转换为 void*
    int* intPtr2 = reinterpret_cast<int*>(voidPtr2); // 从 void* 转换回 int*


    // 这里展示了一个不安全的转换
    double* doublePtr = reinterpret_cast<double*>(intPtr2); // 从 int* 到 double* 的不安全转换


    std::cout << "intPtr points to: " << *intPtr << std::endl;
    std::cout << "intPtr2 points to: " << *intPtr2 << std::endl;
    std::cout << "doublePtr points to: " << *doublePtr << std::endl; // 可能导致未定义行为


    return 0;
}


所以为什么需要reinterpret_cast?

当需要将一个类型的指针转换为另一个类型的指针时,就需要用到,但是它的使用一定是心理有数的,确保不会出现未定义的行为。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4