C++中的类型转换详解:隐式转换、显式转换和四种命名的强制类型转换

本文详细介绍了C++中的隐式类型转换、显式类型转换,特别是static_cast、dynamic_cast和reinterpret_cast的作用、用法和注意事项,强调在编程中应优先使用C++风格的类型转换以确保类型安全。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、隐式类型转换:系统自动进行,不需要程序人员的介入

    int m = 3 + 45.6;//48  把小数部分截掉,也属于隐式类型转换的一种行为。
    double n = 3 + 45.6;//48.600000000000001

    二、显式类型转换(强制类型转换)

    int k = 5 % 3.2;//语法错误
    int k = 5 % (int)3.2;//OK,C语言风格的强制类型转换
    int k = 5 % int(3.2);//函数风格的强制类型转换,C语言也是

    C++强制类型转换分为4种:我们现在写程序应该使用C++风格的强制类型转换:
    这4种强制类型转换,分别用于不同的目的每一个都又有一个不同的名字。提供4种类的目的:
      提供更丰富的含义和功能,更好的类型检查机制,以及方便代码的书写和维护
      a)static_cast
      b)dynamic_cast
      c)const_cast
      d)reinterpret_cast

    这四个强制类型转换都被称为“命名的强制类型转换(因为他们的每一个都有一个名字并且名字不相同)”

    通用形式:
    强制类型转换名<type>(express);
    强制类型转换名,是上边的的,a,b,c,d四个名字之一。

    type:转换的目标类型
    express:你要转换的值(你要转换的是谁)

(2.1)static_cast:静态转换,大家就理解成“正常转换”,编译的时候就会进行类型转换检查

代码中要保证转换的安全性和正确性,static_cast含义跟C语言的强制类型转换这种感觉差不多

C语言风格的强制类型转换,以及编译器能够进行的隐式转换,都可以用static_cast类显式完成

 可用于:


    a)相关类型转换,比如整型和实型之间的转换

    double f = 100.34f;
    int i = (int)f;//C语言风格的类型转换
    int i1 = static_cast<int>(f);//C++风格的类型转换


    b)后续学习类的时候类型转换成父类类型(继承关系),也能用这个static_cast转

    class A{};
    class B:public A{};
    B b;
    A a = static_cast<A>(b);//把子类转成父类的对象。


    c)void *与其他类型指针之间的转换,void* :无类型指针:可以指向任何类型的指针(万能指针)

    int i = 100;
    int* p = &i;
    void* q =static_cast<int *>(p);//int *转成void *;
    int* db =static_cast<int*>(q);


    不可用于:


    a)一般不能用于指针类型之间的转换 比如:int*转double*,float*转double*等

    double f = 100.0f;
    double* pf = &f;
    int *i=static_cast<int*>(pf);//不可以
    float* fd = static_cast<float*>(pf);//不可以

(2.2)dynamic_cast:主要用来 运行时类型识别和检查。主要用来父类型和子类型之间的类型转换

(父类型指针指向子类型对象,然后用dynamic_cast把父指针类型转换往子指针类型转)
           第三章第十节会详细讲解,dynamic_cast这里不多说

  (2.3)const_cast:去除指针 或者引用的const属性。该转换能够将const性质去掉,编译时就会进行类型转换

    const int ai = 90;
    int ai2 = const_cast<int>(ai);//不行,ai不是指针也不是引用无法转
    const int* pai = &ai;
    int* pai2 = const_cast<int*>(pai);//语法正常
    *pai2 = 120;//这种写值行为 是属于一种 未定义行为 。大家不要这么干
    cout << ai << endl;
    cout << *pai << endl;//调试时ai=120 *pai=120但打印的时候90和120,
    //怪异行为*pai2=120;

 (2.4)reinterpret_cast:编译的时候就会进行类型转换的检查

reinterpret_cast:重新解释。将操作数内容解释为另一种不同的类型(能把操作数的类型都转了)
    处理无关类型的转换。也就是两个操作数类型之间没有关系。就等于可以乱转,自由转。怎么转都行,很随意。


    常用于如下3种转换:

    a)将一个整型(地址)转换成指针

​
    int i = 10;
    int* p1 = &i;
    int* p2 = reinterpret_cast<int*>(&i);
    char* pc = reinterpret_cast<char*>(p1);

​


    b)一种指针类型转换成另一种类型指针,按照转换后的内容重新解释内存的内容;

    int i = 10;
    int* pi = &i;
    void* pvoid = reinterpret_cast<void*>(pi);
    int* pi2 = reinterpret_cast<int*>(pvoid);
    //被认为危险的类型转换,随便转怎么搞都行,编译器都不报错


    c)也可以从一个指针类型转换为整型。
   

    int iv1 = 100;
    long long lvl = 8888889889;
    int* piv1 = (int*)iv1;//C语言风格


    总结:

    (1)强制类型转换,不建议使用。强制类型转换能够抑制编译器报错
    (2)主要目的:认识这些强制类型转换符,方便大家阅读别人代码
    (3)资料说:reinterpret_cast危险。使用const_cast意味着设计缺陷
    (4)如果实在需要使用类型转换,不要再使用C语言风格的类型转换了,而用C++风格的类型转换
    (5)一般static_cast和 reinterpret_cast就能够很好的取代C语言风格的类型转换

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值