四个强制类型转换reinterpret_castconst_caststatic_cast dynamic_cast及比较

51 篇文章 1 订阅

四个强制类型转换reinterpret_cast/const_cast/static_cast /dynamic_cast及比较

reinterpret_cast

reinterpret_cast 是一种 C++ 转换运算符,允许程序员在不更改原始对象的情况下将指针或引用转换为不同的类型。 它是一个非常强大且具有潜在危险的运算符,应谨慎使用。

reinterpret_cast 运算符可用于在指针和不相关类型的引用之间进行转换,或将数据对象的位重新解释为不同的类型。 这是一个例子:

int i = 42;
float* fp = reinterpret_cast<float*>(&i);

在此示例中,我们有一个值为 42 的整数“i”。然后我们使用“reinterpret_cast”创建一个指向浮点数“fp”的指针,它获取“i”的地址并将其视为指向“浮点数”的指针。 这意味着 fp现在指向与i相同的内存位置,但将i的位视为float`

请注意,reinterpret_cast 不执行任何类型检查或转换。 它只是将对象的位重新解释为不同的类型。 这意味着错误地使用“reinterpret_cast”会导致未定义的行为,例如读取或写入无效的内存位置。

因此,“reinterpret_cast”只应在绝对必要时使用,并且要透彻了解所涉及的类型和潜在风险。

const_cast

const_cast 是一种 C++ 转换运算符,允许程序员删除或添加变量或对象的常量。 当程序员想要修改声明为“const”的变量或对象,或将“const”添加到非 const 变量或对象时,会使用它。

这是一个例子:

void print(int* ptr) {
    std::cout << *ptr << std::endl;
}

int main() {
    const int i = 42;
    const int* ptr = &i;
    int* ptr2 = const_cast<int*>(ptr);
    *ptr2 = 7;
    print(const_cast<int*>(ptr));
    return 0;
}

在此示例中,我们有一个值为 42 的常量整数“i”和一个指向“i”的指针“ptr”。 我们使用 const_cast 创建一个非常量指针 ptr2 指向与 ptr 相同的内存位置。 然后我们通过将 ptr2 设置为 7 来修改 i 的值。

print 函数接受一个指向整数的非常量指针并打印它的值。 我们再次使用 const_cast 将 ptr(常量指针)传递给 print。

请注意,使用 const_cast 修改 const 对象可能很危险,应谨慎操作。 修改 const 对象可能会导致未定义的行为和意外结果,因此只有在必要时才应该这样做。

static_cast

static_cast 是一种 C++ 转换运算符,允许程序员执行已知在编译时安全的类型转换。 它可用于相关类型之间的转换,例如将派生类指针转换为基类指针,或执行算术转换,例如将整数转换为浮点数。

这是一个例子:

int main() {
    int i = 42;
    float f = static_cast<float>(i);
    std::cout << f << std::endl;

    Base* base = new Derived();
    Derived* derived = static_cast<Derived*>(base);
    derived->doSomething();

    return 0;
}

在此示例中,我们有一个值为 42 的整数“i”。我们使用“static_cast”将“i”转换为浮点数“f”,这是安全的,结果是“f”的值为 42.0。

我们还有一个基类“Base”和一个派生类“Derived”,并创建一个“Derived”类型的新对象并将其赋值给一个“Base*”类型的指针。 然后我们使用 static_castBase* 指针转换为 Derived* 指针,这是安全的,因为我们知道指向的对象实际上是一个 Derived 对象。 然后我们可以通过 Derived* 指针调用 Derived 类的 doSomething() 函数。

请注意,static_cast 是一个编译时运算符,因此它无法执行运行时安全检查。 仅当程序员确定转换是安全的时才应使用它。 如果对转换的安全性有任何疑问,则应改用“dynamic_cast”。

dynamic_cast

dynamic_cast 是一种 C++ 转换运算符,它允许程序员在运行时执行多态类型的安全向下转换。 当需要将基类指针或引用转换为派生类指针或引用时使用它,但程序员不确定转换是否安全。

这是一个例子:

class Base {
public:
    virtual void doSomething() {
        std::cout << "Base doing something" << std::endl;
    }
};

class Derived : public Base {
public:
    void doSomething() override {
        std::cout << "Derived doing something" << std::endl;
    }
};

int main() {
    Base* base = new Derived();
    Derived* derived = dynamic_cast<Derived*>(base);
    if (derived) {
        derived->doSomething();
    } else {
        std::cout << "Invalid cast" << std::endl;
    }
    delete base;
    return 0;
}

在这个例子中,我们有一个基类“Base”和一个派生类“Derived”。 我们创建一个 Derived 类型的新对象,并将其分配给 Base* 类型的指针。 然后我们使用 dynamic_castBase* 指针转换为 Derived* 指针。 如果转换成功,我们通过 Derived* 指针调用 Derived 类的 doSomething() 函数。 如果转换不成功,我们会打印一条错误消息。

请注意,dynamic_cast 是一个运行时运算符,因此它可以执行检查以确保转换是安全的。 只有在至少具有一个虚函数的多态类上使用“dynamic_cast”才是安全的。 此外,dynamic_cast 只能用于转换指针或引用,不能用于转换对象。

如果转换不安全,dynamic_cast 为指针返回一个空指针或为引用抛出 std::bad_cast 异常。 因此,在使用指针或引用之前检查“dynamic_cast”的结果很重要。

比较

reinterpret_castconst_caststatic_castdynamic_cast 都是用于类型转换的 C++ 转换运算符。 但是,它们在功能和用法上有所不同:

  • reinterpret_cast 是一个非常强大的低级运算符,允许程序员重新解释对象的位,就好像它是不同的类型一样。 它用于在不相关类型的指针和引用之间进行转换,或者将数据对象的位重新解释为不同的类型。 它不执行任何类型检查或转换,应谨慎使用。

  • const_cast 用于删除或添加变量或对象的 const-ness。 它用于修改声明为 const 的变量或对象,或将 const 添加到非 const 变量或对象。

  • static_cast 用于执行已知在编译时安全的安全类型转换。 它可用于相关类型之间的转换,例如将派生类指针转换为基类指针,或执行算术转换,例如将整数转换为浮点数。

  • dynamic_cast 用于在运行时执行多态类型的安全向下转换。 当需要将基类指针或引用转换为派生类指针或引用时使用它,但程序员不确定转换是否安全。 它执行运行时检查以确保转换是安全的,并返回空指针或抛出 std::bad_cast 异常(如果不是)。

通常,应谨慎使用 reinterpret_castconst_cast,因为如果使用不当,它们很容易导致未定义的行为。 在执行已知在编译时安全的类型转换时,static_cast 是更安全的选择,而在运行时执行多态类型的向下转换时,dynamic_cast 是最安全的选择。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
C++中有四种强制类型转换,分别是reinterpret_cast、const_cast、static_cast和dynamic_cast。 reinterpret_cast用于进行底层的重新解释转换,可以将一个指针或引用转换为其他类型的指针或引用,甚至可以将指针转换为整数类型。但是使用reinterpret_cast需要非常小心,因为它是一种非常危险的操作,可能会导致未定义的行为。 const_cast用于移除const属性,可以将const修饰的变量或指针转换为非const类型。这可以用于去除const限定符,从而修改被const修饰的变量的值。 static_cast用于进行常见的类型转换,可以将一个表达式转换为另一种类型,例如基本数据类型之间的转换、父类指针或引用转换为子类指针或引用、以及void指针和任意类型的指针之间的转换。但是需要注意,在进行父类到子类的转换时,只有当父类指针或引用实际上指向了一个子类对象时,才能进行成功的转换。 dynamic_cast用于在继承关系中进行安全的向下转型(downcasting)。它可以将一个父类指针或引用转换为子类指针或引用,同时会进行类型检查,确保转换是安全的。如果转换失败,dynamic_cast会返回一个空指针或抛出一个std::bad_cast异常。 这四种强制类型转换在不同的场景下有不同的应用,可以根据具体的需求选择合适的转换方式。但是需要注意,在使用这些强制类型转换时,一定要谨慎和慎重,确保转换的安全性和正确性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++中的类型转换static_cast、dynamic_cast、const_cast和reinterpret_cast总结](https://download.csdn.net/download/weixin_38629976/12808232)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [C++的四种类型转换reinterpret_cast/const_cast/static_cast /dynamic_cast](https://blog.csdn.net/salmonwilliam/article/details/113941785)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [C++四种cast转换(const_cast、static_cast、dynamic_cast、reinpreter_cast)类型转换运算符](https://blog.csdn.net/Dontla/article/details/130792118)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

What’smean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值