• c++类型转换


    目录

    1.隐式类型转换和强制类型转换

    2.隐式类型转换带来的危险

    3.c++提供的标准类型转换关键字

    4.总结


    1.隐式类型转换和强制类型转换

    c语言的类型转换可以分为隐式类型转换和强制类型转换。

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. double a = 3.14;
    6. int b = a;
    7. cout << b << endl;
    8. int* p = &b;
    9. int pp = (int)p;
    10. cout << pp << endl;
    11. return 0;
    12. }

    这里的转换的前提都是这两个类型意义相近。

    ps:要区别继承中的切割和隐式类型转换。

    1. class A
    2. {
    3. public:
    4. A()
    5. :_a(0)
    6. {}
    7. private:
    8. int _a;
    9. };
    10. class B :public A //继承A
    11. {
    12. public:
    13. B()
    14. :_b(0)
    15. ,A()
    16. {}
    17. private:
    18. int _b;
    19. };
    20. int main()
    21. {
    22. B b;
    23. A a = b;//一种原生支持的切割
    24. return 0;
    25. }

    我们要知道隐式类型转换的共性是要生成一个临时对象,明显将b赋值给a的时候不会产生临时对象。只需要将这种方式作为编译器支持的原生方式转换就好。


    2.隐式类型转换带来的危险

    1. #include
    2. using namespace std;
    3. void Move(size_t pos)
    4. {
    5. int end = 4;
    6. while (end >= pos) //发生了隐式类型转换,将int的end转换成了size_t无符号数
    7. {
    8. //arr[end + 1] = arr[end]; 向后挪
    9. end--;
    10. }
    11. }
    12. int main()
    13. {
    14. Move(0);
    15. return 0;
    16. }

    这段程序死循环了。

    原因是:当end减到-1才应该退出循环,但是因为end和pos在表达式的两边。且两个数意义相近

    ,因此end变成了无符号数,-1就变成了整形的最大值(要了解负数补码和无符号数的定义)。

    end突然搞那么大,就必然跑不出去了奥。


    3.c++提供的标准类型转换关键字

    a.static_cast

    和隐式类型转换一样。

    问题:不支持类型差距太大的转换 

     

    b.reinterpret_cast

    问题: 不支持去除const属性

     

    c.const_cast

    常用来给const变量赋值(去除const属性):

    1. const int a = 3;
    2. int* pp = const_cast<int*>(&a);
    3. *pp = 4;
    4. cout << a << endl;

    这里有一个奇怪的现象:

    显示的结果为a的值依然是3,再通过调试看看内存中a的值:

     

     太神奇了,内存中显示a是4诶。

    实际上,这和ide的处理有关,在vs环境下const变量并不是存于常量区中。而是存在一个特殊寄存器中,本质也在栈中。调用时,内存中的const变量就算在内存中发生了变化,但由于已经被寄存器将之前的值读出了,所以我们看见的结果没有发生变化。


    d.dynamic_cast

    dynamic_cast用于父子类的向下赋值,向上赋值原生支持(切割)。

    1. class A
    2. {
    3. public:
    4. virtual void f() {}
    5. };
    6. class B : public A //继承A
    7. {};
    8. void fun(A* pa)
    9. {
    10. // dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回。
    11. B* pb = dynamic_cast(pa);
    12. //转换为B*(子类)
    13. if (pb)
    14. {
    15. cout << "转换成功" << endl;
    16. }
    17. else
    18. {
    19. cout << "转换失败" << endl;
    20. }
    21. }
    22. int main()
    23. {
    24. A a; B b;
    25. fun(&a);
    26. fun(&b);
    27. }

     若是传入A(父类),是一种不安全的转换(可能存在越界问题)。

    看图:

     


    4.总结

    建议使用c++提供的指定类型转换关键字,这种方式更加安全。可以避免隐式类型转换的坑,并且还提供了dynamic_cast和const_cast来处理特殊问题。

  • 相关阅读:
    JSP response对象简介说明
    0-1 背包问题
    Android-S Emulator
    发生OOM时JVM会退出吗
    c++还原简单的vector
    【cmake】cmake生成Visual Studio工程后的INSTALL项目使用
    《动手学深度学习 Pytorch版》 9.1 门控循环单元(GRU)
    D. a-Good String(递归+二分)
    02-线性结构4 Pop Sequence
    常用的开源网关 API Gateway
  • 原文地址:https://blog.csdn.net/xiao_xiao21/article/details/128090847