【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)

1. static_cast

实现C++种内置基本数据类型之间的相互转换,不能用于两个不相关类型进行转换

例如:将整形数据转换为浮点型

  1. c语言方式
int a = 8;
int b = 3;
double result = (double)a / (double)b;
  1. C++方式
int a = 8;
int b = 3;
double result = static_cast<double>(a) / static_cast<double>(b);

格式如下:

static_cast<类型>(变量表达式)

应用场景:

  • 用于类层次结构中基类和派生类之间引用或指针的转换。
    进行上行转换(把派生类的指针或引用转换成基类表示)是安全的。
    进行下行转换(把基类的指针或引用转换成派生类表示),由于没有动态类型检查,不安全。
  • 用于基本数据类型之间的转换
  • 把空指针转换成目标类型的空指针
  • 把任何类型的表达式转换成void类型

2. dynamic_cast

用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)

dynamic_cast< type_id >(expression)

  • type_id 必须是类的指针、类的引用或者void*。
  • 主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
  • dynamic_cast只能用于含有虚函数的类;
  • 进行上行转换的时候,与static_cast 的作用一样。下行转换的时候,具有类型检查的功能,比static_cast更安全。
  • dynamic_cast会先检查是否能转换成功,如果能则转换,不能则返回0。
class B
{
public:
    int m_iNum;
    virtual void foo();
};
 
class D : public B
{
public:
    char *m_szName[100];
};
 
void func(B *pb)
{
    D *pd1 = static_cast(pb);
    D *pd2 = dynamic_cast(pb);
}

如果pb指向一个D类型的对象,pd1 和 pd2 是一样的,并且这两个指针执行D类型的任何操作都是安全的。

如果指向B的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作是不安全的。pd2将是一个空指针。

B要有虚函数

这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。

3. const_cast

c语言中,const是用来限定变量,表示该变量的值不能更改。

const_cast 是用来强制去掉这种不能被修改的常数特性。不是去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,对象必须为指针或引用。

const_cast<type_id>(expression)

用来修改类型的const或volatile属性。

常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

include<iostream>
using namespace std;
 
int main()
{
    const int a = 10;
    const int * p = &a;
    int *q;
    q = const_cast<int *>(p);
    *q = 20;    //fine
    cout <<a<<" "<<*p<<" "<<*q<<endl;
        cout <<&a<<" "<<p<<" "<<q<<endl;
    return 0;
}

定义了一个普通指针q。将p通过const_cast去掉其常量性,并赋值给q指针。

4. reinterpret_cast

通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。

reinterpret_cast<type_id>(expression)

type_id 必须是一个指针、引用、算术类型、函数指针、成员指针。

应用场景

改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整形转换为指针或引用。

int *a = new int;
double *d = reinterpret_cast<double *>(a);

5. 为什么要需要四种类型转换?

C风格的转换格式很简单,但是也有缺点:

  • 过于粗暴,可以在任意类型之间转换,很难判断其正确性。
  • 隐式转换有些情况会出问题:比如精度丢失。
  • 显示转换和隐式转换混合在一起,很难快速定位全部的强制转换语句。

但是在实际的工程中强制转换是不可避免的,为此C++提供的四种强制类型转换提供了更加安全可靠的转换。

  • 11
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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 ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值