9 新型的类型转换

1 C 语言中的强制类型转换

  • C 方式的强制类型转换

    • (Type)(Expression)
    • Type(Expression)
  • 示例:粗暴的类型转换

    • Demo

      #include <stdio.h>
      
      typedef void(PF)(int);  //定义一个函数类型
      
      struct Point
      {
          int x;
          int y;
      };
      
      int main()
      {
          int v = 0x12345;
          PF* pf = (PF*)v;  //这里将0x12345转化为一个函数地址,很可能出错
          char c = char(v);
          Point* p = (Point*)v;
          
          pf(5);
          
          printf("p->x = %d\n", p->x);
          printf("p->y = %d\n", p->y);
      
          return 0;
      }
      
    • 编译运行

      段错误
      
  • C 方式强制类型转换存在的问题

    • 过于粗暴:任意类型之间都可以进行转换,编译器很难判断其准确性
    • 难以定位:在源码中无法快速定位所有使用强制类型转换的语句

2 新式类型转换

  • 新式类型转换以 C++ 关键字的方式出现

    • 编译器能够帮助检查潜在的问题
    • 非常方便的在代码中定位
    • 支持动态类型识别(dynamic_cast
  • C++ 将强制类型转换分为 4 种不同的类型

    • static_castconst_castdynamic_castreinterpret_cast
    • 用法:xxx_cast<Type>(Expression)
  • static_cast 强制类型转换

    • 用于基本类型间的转换
    • 不能用于基本类型指针间的转换
    • 用于有继承关系类对象之间的转换和类指针之间的转换
  • const_cast 强制类型转换

    • 用于去除变量的只读属性
    • 强制转换的目标类型必须是指针或引用
  • reinterpret_cast 强制类型转换

    • 用于指针类型间的强制转换
    • 用于整数指针类型间的强制转换
  • dynamic_cast 强制类型转换

    • 用于有继承关系的类指针间的转换
    • 用于有交叉关系的类指针间的转换
    • 具有类型检查的功能
    • 需要虚函数的支持
  • 示例:新式类型转换

    • Demo

      #include <stdio.h>
      
      void static_cast_demo()
      {
          int i = 0x12345;
          char c = 'c';
          int* pi = &i;
          char* pc = &c;
          
          c = static_cast<char>(i);  //ok: int->char
          pc = static_cast<char*>(pi);  //error: int*->char*
      }
      
      void const_cast_demo()
      {
          const int& j = 1;
          int& k = const_cast<int&>(j);  //去除引用的常量属性
          
          const int x = 2;
          int& y = const_cast<int&>(x);
          
          int z = const_cast<int>(x);  //error: 只能是引用或指针
          
          k = 5;
          
          printf("k = %d\n", k);  // 5
          printf("j = %d\n", j);  // 5
          
          y = 8;
          
          printf("x = %d\n", x);  // 2
          printf("y = %d\n", y);  // 8
          printf("&x = %p\n", &x);  // 0xbf93d3c0
          printf("&y = %p\n", &y);  // 0xbf93d3c0
      }
      
      void reinterpret_cast_demo()
      {
          int i = 0;
          char c = 'c';
          int* pi = &i;
          char* pc = &c;
          
          pc = reinterpret_cast<char*>(pi);  //ok: int*->char*
          pi = reinterpret_cast<int*>(pc);  //ok: char*->int*
          pi = reinterpret_cast<int*>(i);  //ok: int->int*
          c = reinterpret_cast<char>(i);  //error: int->char
      }
      
      void dynamic_cast_demo()
      {
          int i = 0;
          int* pi = &i;
          char* pc = dynamic_cast<char*>(pi);  //error
      }
      
      int main()
      {
          static_cast_demo();
          const_cast_demo();
          reinterpret_cast_demo();
          dynamic_cast_demo();
          
          return 0;
      }
      
    • 编译

      test.cpp: In function ‘void static_cast_demo()’:
      test.cpp:11: error: invalid static_cast from type ‘int*’ to type ‘char*’
      test.cpp: In function ‘void const_cast_demo()’:
      test.cpp:22: error: invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type
      test.cpp: In function ‘void reinterpret_cast_demo()’:
      test.cpp:47: error: invalid cast from type ‘int’ to type ‘char’
      test.cpp: In function ‘void dynamic_cast_demo()’:
      test.cpp:54: error: cannot dynamic_cast ‘pi’ (of type ‘int*’) to type ‘char*’ (target is not pointer or reference to class)
      
posted @ 2020-09-21 21:44  nxgy  阅读(102)  评论(0编辑  收藏  举报