• C++---类型转换


    C语言中的类型转换

    在学习C语言的时候,如果赋值运算符左右两边的类型不同。或者在调用函数的时候,形参和实参类型不匹配,或者返回值类型与接收返回值类型不一致的时候,就需要发生类型转换。

    C语言中总共有两种类型转换方式:隐式类型转换和显式类型转换。

    1. 隐式类型转换:编译器在编译阶段自动进行,能转就转,不能转就报错。
    2. 显式类型转换:需要自己处理
    1. void Test ()
    2. {
    3. int i = 1;
    4. // 隐式类型转换
    5. double d = i;
    6. printf("%d, %.2f\n" , i, d);
    7. int* p = &i;
    8. // 显示的强制类型转换
    9. int address = (int) p;
    10. printf("%x, %d\n" , p, address);
    11. }

    C++的类型转换

    C++兼容C语言,C语言中的类型转换放到C++中也可以使用,并且C++提出了自己的类型转换风格。

    cast-name<type>(expression)

    type是要转换的目标类型,expression是要转换的值。

    C++强制类型转换

    标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符。

    static_castreinterpret_castconst_castdynamic_cast

    static_cast

    任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换

    1. int main()
    2. {
    3. double d = 12.34;
    4. int a = static_cast<int>(d);
    5. cout << a << endl;
    6. return 0;
    7. }

    reinterpret_cast

    reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,

    1. int a = 1;
    2. int* pa = &a;
    3. char* pstr = reinterpret_cast<char*>(pa);

    要牢记pstr指向的真实对象是一个int而非字符。如果你在pstr中存了字符,在次输出a的时候,输出的会是ASCII码。

    const_cast

    const_cast只能改变运算对象的底层const

    const_cast最常用的用途就是删除变量的const属性,方便赋值

    1. int main()
    2. {
    3. volatile const int a = 2;
    4. int* p = const_cast<int*>(&a);
    5. *p = 3;
    6. cout << a << endl;
    7. return 0;
    8. }

    dynamic_cast

    前面的多态和继承里面提到过切片操作,子类的指针类型或者引用类型可以赋值给父类。

    dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
    向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
    向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
    注意:

    1. dynamic_cast只能用于父类含有虚函数的类
    2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
    1. class Father
    2. {
    3. public:
    4. virtual void f()
    5. {
    6. ;
    7. }
    8. };
    9. class Son : public Father
    10. {};
    11. void func(Father* s)
    12. {
    13. if (s)
    14. {
    15. cout << "转换成功" << endl;
    16. }
    17. else
    18. {
    19. cout << "转换失败" << endl;
    20. }
    21. }
    22. int main()
    23. {
    24. Father fa;
    25. Son so;
    26. Son* son = dynamic_cast<Son*>(&fa);
    27. Father* father = dynamic_cast<Father*>(&so);
    28. func(son); // 转换失败
    29. func(father); // 转换成功
    30. return 0;
    31. }


    注意
    强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是
    否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用
    域,以减少发生错误的机会。强烈建议:避免使用强制类型转换

  • 相关阅读:
    通信系统中ZF,ML,MRC以及MMSE四种信号检测算法误码率matlab对比仿真
    C++11 右值引用核心
    ‘Xcode Unable to execute command: Segmentation fault: 11‘
    blender 场景灯光基础设置
    Ubuntu16.04配置NTP时间同步
    jQuery
    分布式并行训练(DP、DDP、DeepSpeed)
    Kali 基础命令(一)
    抽象工厂模式
    Dubbo的使用
  • 原文地址:https://blog.csdn.net/weixin_73888239/article/details/133838728