第三章 - 处理数据

一,C++类型转换

C++丰富的类型允许根据需求选择不同的类型,这也使计算机的操作更加复杂。例如,将两个short值相加涉及到的硬件编码指令可能与将两个long值相加不同。由于有11种整型与3种浮点型,据此计算机要处理大量不同的情况,尤其是对不同的类型进行运算时。为处理这些潜在的混乱,C++自动执行很多类型转换,例如:

1.1,初始化与赋值进行的转换

int a = 20;
long b = a;

将一个值赋给取值范围更大的类型通常不会导致什么问题,然而,将一个很大的值赋给较小范围的类型会降低精度。将浮点类型的值赋给整形变量可能会导致两个问题,首先,将浮点值转换为整形会将数字截短(除掉小数部分)。其次,double值对int来说可能太大。

1.2,表达式中的转换

当同一个表达式包含不同的算术类型时,在这种情况下,C++将自动执行两种转换。首先,一些类型在出现时便会自动转换;其次,有些类型在与其他类型同时出现在表达式中时将被转换。先看自动转换,在计算表达式时,C++将bool、char、short转换为int,这些转换称为整形提升。将不同类型进行算术运算时,也会进行一些转换,例如将int与float相加时。当涉及两种类型时,较小的类型将被转换为较大的类型。

1.3,强制类型转换

C++允许通过强制类型转换机制显示进行类型转换,强制类型转换的格式有两种格式,如下:

(typename) value;
 typename (value);

1.4,C风格的类型转换存在的问题

C风格的类型转换格式很简单(TYPE)EXCEPTION,但是C风格的类型转换有不少的缺点。有的时间C风格的转换是不合适的,因为它可以在任意类型之间转换。把一个指向const对象的指针转换成指向non const对象的指针,把一个基类指针转换成派生类指针,这两种转换之间的区别很大,但是传统的C风格的类型转换并没有区分这些。C风格的类型转换的另一个缺点是不容易查找,它是有一个括号加一个标识符组成,这样的东西在C++程序里很多,C++为了克服这些缺点引入四个新的类型转换运算符。

二,C++ 类型转换运算符

2.1,const_cast

作用:将对象的常量性移除,将一个常对象转换成非常的对象。
实例:

class Student{
public:
    string name;
public:
    Student(string name):name(name){}
};

int main(){
    const Student *p = new Student("zhangsan");
    Student *pObj = const_cast<Student *>(p);  //把一个指向常对象的指针,转换成指向非常对象的指针
    pObj->name = "";
}

2.2,static_cast

作用:强迫进行隐式转换。
实例:

  • 用于基类和派生类之间的指针或引用的转换,这种转换把派生类的指针或引用转换为基类是安全的。但是,把基类指针或引用转换为派生类时,由于没有进行动态类型检测,所以是不安全的。
  • 把void类型的指针转换成目标类型的指针(不安全),需要进行强制类型转换。
  • void指针可以指向任意类型的数据,即可用任意数据类型的指针对void指针赋值。
  • 用于内置的基本的数据类型之间的转换。

2.3,dynamic_cast

作用:用来执行判断是否可以进行”安全向下类型转型”,即一个基类指针是否可以转换成一个派生类指针。
实例:

Type *q = dynamic_cast<Type *>(p);
q = dynamic_cast<Type *>(p);

当p实际指向的类对象是Type类对象或是Type类的派生类的对象,返回一个Type *,否则返回值为NULL。

int main(){
    Base *pBaseObj = new Derived(10, 100);  //基类对象指针实际指向的是一个派生类对象
    Derived *pDerivedObj = dynamic_cast<Derived*>(pBaseObj);
    if(pDerivedObj){
        pDerivedObj->test();
    } else {
        cout<<"std::bad_cast"<<endl;
    }

    Base *pBase = new Base(10);  //基类对象指针指向的是一个基类对象
    Derived *pDerived = dynamic_cast<Derived*>(pBase);
    if(pDerived){
        pDerived->test();
    } else {
        cout<<"std::bad_cast"<<endl;
    }
}

输出结果:

Derived test.  
std::bad_cast  

Process returned 0 (0x0)   execution time : 0.009 s  
Press any key to continue.  

2.4,reinterpret_cast

作用: interpret是解释的意思,reinterpret即为重新解释,为二进制形式的数据重新解释,但是不改变其值。
实例:

int main(){
    int i;
    char *ptr = "hello";
    i = reinterpret_cast<int>(ptr);
    cout<<i<<endl;
}

输出结果:

4644900

Process returned 0 (0x0)   execution time : 0.048 s
Press any key to continue.

2.5,使用C++而不是C风格类型转换的优点

  1. 类型转换在代码中比较容易识别。
  2. 各类型转换运算符的功能越单一,编译器越可能诊断出错误应用。例如,想把常量性去掉除非使用新式的const_cast否则无法通过编译。

猜你喜欢

转载自blog.csdn.net/cloud323/article/details/80879889