C++ primer读书笔记——5.12 类型转换

来源:互联网 发布:机锋刹那版主淘宝店 编辑:程序博客网 时间:2024/04/29 16:31

在C++中存在两种形式的类型转换,一种是我们没有意识到的隐式类型转换(implicit type conversion),一种是我们故意做的显示类型转换(也就是强制类型转换)。
一、隐式类型转换
1. 何时发生隐式类型转换
  a) 在混合类型的表达式中,其操作数被转换为相同的类型;
    int ival;  double dval;
    ival >= dval;
  b) 用作条件的表达式被转换为bool类型;
    wile (cin)  //cin converted to bool
  c) 用表达式初始化某个变量,或将表达式赋值给某个变量,则该表达式转换为该变量的类型。  
    int ival = 3.14;  //3.14 converted to int
2. 主要分类
  a) 算术转换
  个人认为,这种算术转换就是将所有的类型统一为表示范围最长的那个类型,如果要是两个类型的字节一样长,则遵循如下的规则:整型向浮点数转换;有符号向无符号的转换。这种转换方式可能会因为将一个有符号的负数转换为无符号的数,变得很大,最后导致程序运行错误。
  b) 指针转换
  在使用数组时,大多数情况下数组都会自动转换为指向第一个元素的指针。但存在如下的例外:数组用作取地址(&)操作符的操作数、或sizeof操作符的操作数、或用数组对数组的引用进行初始化时,不会将数组转换为指针。
  指向任意类型的指针都可以转换为void*类型;
  整数数值常量0可转换为任意类型指针。 PS:给指针赋值时,最好使用NULL
  c) 转换为bool类型
  0为false,非0为true
  d) bool类型转换为算术类型
  将bool类型转换为布尔类型时,true变成1,而false则为0。
  e) 枚举类型的转换
  根据机器的定义和枚举类型的最大值,枚举类型将至少提升为int类型,还可以提升为unsigned int、long或unsigned long。
  f) 由标准库定义的类型转换
  istream作为条件参数时,会将流的状态转换为bool类型。
  eg: while (cin >> s)
二、显示类型转换
1. 何时需要强制类型转换
  a) 覆盖通常的标准转换
  eg: double dval;  int ival;  
    ival *= static_cast<int>(dval);
  b) 存在多种转换时,选择一种特定的类型转换
2. 命名的强制类型转换
  a) 一般的形式
    cast-name<type>(expression);
  b) dynamic_cast,完全被用来进行指针的操作。它可以用来进行任何可以隐含进行的转换操作以及它们被用于多态类情况下的方向操作。然而与static_cast不同的是, dynamic_cast 会检查后一种情况的操作是否合法,也就是说它会检查类型转换操作是否会返回一个被要求类型的有效的完整的对象。
  c) const_cast,添加或删除const特性
  d) static_cast,可以执行所有的隐式类型转换,以及他们的反向操作。
  e) reinterpret_cast,提供指针和指针或指针和整型之间的转换,这种转换仅仅是二进制内容的拷贝,并不涉及到类型的检查。
  eg: int *ip;

    char *pc = reinterpret_cast<char *>(ip);

  f) typeid

ANSI-C++ 还定义了一个新的操作符叫做 typeid ,它检查一个表达式的类型:
    typeid (expression)
  这个操作符返回一个类型为type_info的常量对象指针,这种类型定义在标准头函数中。这种返回值可以用操作符 == 和 != 来互相进行比较,也可以用来通过name()函数获得一个描述数据类型或类名称的字符串。

3. 旧式强制类型转换
  旧式的强制类型转换符号有两种形式:
    type (expr);  // Function-styple cast notation
    (type) expr;  // C-language-style cast notation

  旧式的强制类型转换相当于依次尝试如下的转换的方式:static_cast --> const_cast --> reinterpret_cast


个人总结:显示类型转换中,const_cast是用于添加或删除const属性;static_cast用于可以进行隐式类型转换的类型之间的转换;reinterpret_cast直接是二进制内容的拷贝,这样是最危险的;dynamic_cast用于继承关系中的指针类型转换,因为可以进行类型检查,所以相对安全一些。


参考文献:

1. 高级类型转换 (Advacned Class Type-casting)

2. 《C++ primer(第四版)》