• 类型转换


    【1】类型转换

    诸位周知,类型分为内置数据类型和自定义数据类型(即就是类)。那么,类型转换也就从这两种情况进行讨论。

    首先,有一个概念的认识:类型转换分为隐式类型转换与显式类型转换。

    所谓隐身类型转换就是由编译器自己执行转换过程,无需程序员介入。

    显式类型转换也称为强制类型转换,一般使用名字命名的强制类型转换操作符。

    【2】隐身类型转换

    (1)在混合类型的表达式中,其操作数被转换为相同的类型:

    1 int iVal;
    2 double  dVal;
    3 iVal >= dVal;  //iVal 转换为 double

    (2)用作条件的表达式被转换为bool类型:

    1 int iVal;
    2 if(iVal)  //iVal转换为bool
    3 while(cin)   //cin转换为bool

    (3)用一表达式初始化某个变量,或将一表达式赋值给某个变量,测该表达式被转换为该变量的类型:

    1 int iVal = 3.14; //3.14转换为int
    2 int *p = 0; //0 转换为空指针类型为int *

    (4)算术转换(有符号与无符号类型之间的转换)

    (5)指针转换

    1 int ia[10];
    2 int *ip = ia; //ia转换为第一个元素的指针

    (6)算术类型与bool类型转换

    1 bool  bVal = true;
    2 int iVal = b;   //iVal == 1 
    3 double pi = 3.14;
    4 bool b2 = pi; //b2 为真
    5 pi = false;   //pi == 0

    (7)转换为枚举类型

    1 enum eVal {a, b, c, d};
    2 int iVal = b;  //iVal  == 1

    (8)转换为const对象

    1 int i;
    2 const int ci = 0;
    3 const int &j = i; //非常量转换为常整型引用
    4 const int *p = &ci;  //转换非常量地址为常量地址

    (9)由标准类型定义的转换

    1 string s;
    2 while(cin>>s)   //将istream类型转换为bool类型

    (10)类中隐身转换

     1 class A
     2 {
     3     int a;
     4 public:
     5     A(int x = 0 ):a(x)
     6     {
     7 
     8     }
     9 };
    10 void main()
    11 {
    12     A obj = 100;  //将整型转换为自定义类型A
    13 }

    【3】显式类型转换

    显式类型转换操作符:static_cast,  const_cast,  dynamic_cast,  reinterpret_cast。

    (1)static_cast

    命名上理解是静态类型转换。如double转换为char。

    1 double dVal = 97.0;
    2 char ch = static_cast<char>(dVal);

    类似于C风格的强制转换。无条件转换,静态类型转换。用于:

    <1>基类和子类之间转换:其中子类指针转换成父类指针是安全的;但是父类指针转换为子类指针是不安全的。(基类与子类之间的动态转换建议使用dynamic_cast)。

    <2>基本数据类型转换。enum, struct, int, char, float等。static_const不能进行无关类型(如非基类和子类)指针之间的转换。

    <3>把空指针转换为目标类型的空指针。

    <4>把任何类型的表达式转换为void类型。

    <5>static_cast不能去掉类型的const,volitale属性(用const_cast)。

    (2)const_cast

    去掉类型的const或volatile属性。

     1 struct SA 
     2 {
     3     int i;
     4 };
     5 
     6 void main()
     7 {
     8     const SA ra;
     9     //ra.i = 10; //直接修改const类型,编译错误
    10     SA &rb = const_cast<SA&>(ra);
    11     rb.i = 10;
    12 }

    (3)dynamic_cast

    有条件转换,动态类型转换,运行时类型安全检查(转换失败返回NULL):

    <1>安全的基类和子类之间转换。

    <2>必须要有虚函数。

    <3>相同基类不同子类之间的交叉转换。但结果是NULL

     1 #include<iostream>
     2 using namespace std ;
     3 
     4 class BaseClass 
     5 {
     6 public:
     7     int m_iNum;
     8     virtual void foo(){};
     9     //基类必须有虚函数。保持多台特性才能使用dynamic_cast
    10 };
    11 
    12 class DerivedClass: public BaseClass 
    13 {
    14 public:
    15     char *m_szName[100];
    16     void bar(){};
    17 };
    18 
    19 void main()
    20 {
    21     DerivedClass* pb = new DerivedClass();
    22     //子类->父类,静态类型转换,正确但不推荐
    23     BaseClass *pd1 = static_cast<DerivedClass *>(pb);
    24     //子类->父类,动态类型转换,正确
    25     BaseClass *pd2 = dynamic_cast<DerivedClass *>(pb);
    26 
    27     
    28     BaseClass* pb2 = new BaseClass();
    29     //父类->子类,静态类型转换,危险!访问子类m_szName成员越界
    30     DerivedClass *pd21 = static_cast<DerivedClass *>(pb2);
    31     //父类->子类,动态类型转换,安全的。结果是NULL
    32     DerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2);
    33 
    34     if(NULL == pd22)
    35     {
    36         cout<<"pd22 == NULL"<<endl;
    37     }
    38 }
    39 
    40 /*
    41 pd22 == NULL
    42  */

    (4)reinterpret_cast

    仅仅重新解释类型,但没有进行二进制的转换:

    <1>转换的类型必须是一个指针、引用、算术类型、函数指针或者成员指针。

    <2>在比特位级别上进行转换。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换为一个整数,再把该整数转换为原类型的指针,还可以得到原先的指针值)。但不能将32bit的实例转成指针。

    <3>最普通的用途就是在函数指针类型之间进行转换。

    <4>很难保证移植性。

     1 #include<iostream>
     2 using namespace std ;
     3 
     4 int doSomething()
     5 {
     6     return 0;
     7 }
     8 //FuncPtr 是一个指向函数的指针,该函数没有参数,返回值类型为 void
     9 typedef void (*FuncPtr) ();
    10 void main()
    11 {
    12     //10个FuncPtrs指针的数组 让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:
    13     FuncPtr funcPtrArray[10];
    14     // 编译错误!类型不匹配,reinterpret_cast可以让编译器以你的方法去看待它们:funcPtrArray
    15 //    funcPtrArray[0] = &doSomething;
    16     //不同函数指针类型之间进行转换
    17     funcPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething);    
    18 }

    总结:

    1:去const属性使用const_cast。

    2:基本类型转换使用static_cast。

    3:多态类之间的类型转换使用dynamic_cast。

    4:不同类型之间的指针类型转换使用reinterpret_cast。

    Good Good Study, Day Day Up.

    顺序  选择  循环  坚持  总结

    作者:kaizen
    声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
    签名:顺序 选择 循环
  • 相关阅读:
    mysql清空表中内容
    Proteus元件查找
    HDG12864F1 proteus仿真取模【PCtoLCD完美版】
    OLED取模(汉字加图片)
    Failed to connect to ESP8266: Timed out waiting for packet header
    AD常用快捷键
    Authentication method 'caching_sha2_password' not supported by any of the available plugins.
    spark阶段学习总结(三)
    spark阶段学习总结(一)
    spark阶段学习总结(二)
  • 原文地址:https://www.cnblogs.com/Braveliu/p/2856046.html
Copyright © 2020-2023  润新知