************ 一、隐式类型转换 ************* C++语言为内置类型定义了一套隐式类型转换。隐式类型转换有如下情形: 1、在混合类型的算术表达式中,所有类型会向最宽的类型转换。这被称为算术类型转换。 算数转换包括两种形式: a、如果可能,所有类型都将提升为最宽的类型已避免数据损失; b、只要表达式中包含的都是整数类型,则均先提升小于int的整型为int再进行其他转换或计算; 2、在赋值表达式中,被赋值的类型(‘=’左边的操作数)将作为目标转换类型。 这时候由于目标转换类型不一定是整个表达式中最宽的数据类型,因此可能会产生数据损失,因此一般编译器会给出个warning。 赋值表达式有多种表现形式,如下: a、直接的’=‘赋值语句; b、将表达式作为参数传递给函数时,这时候函数的形参可以看作‘=’左边的操作数,实际参数作为‘=‘右边的操作数 c、函数体return语句将表达式返回式,这时候函数名作为’=‘左边的操作数,返回的表达式为右边的操作数。 3、类型大小关系: unsigned > signed; long double > double > float > integral types; unsigned long > long / int > bool,unsigned char, signed char,char,w_char, short int; 注:unsigned short int与int的大小关系与机器有关, unsigned int与long的大小关系与机器有关; 当int不足以代表所有unsigned short int值时,两者均转化为unsigned int;当long不足以代表所有unsigned int值时,两者均转换为unsigned long。 枚举类型用能代表所有枚举值的最小的整型类型存储。 ************ 二、显式类型转换 ************* 语法:const_name<type>(expr); 1、const_cast 去除表达式的const/volatile属性。一般用于去除指针的const属性。 例如: const int a = 5; const int * ptr = &a; int * ptr1 = const_cast<int *>(ptr); // okay!! *ptr1 = 8; cout << *ptr1 << endl; cout << *ptr << endl; int b = const_cast<int>(a); //error C2440: 'const_cast' : cannot convert from 'const int' to 'int' cout << b << endl; } 2、static_cast 标准转换基本上都可以用static_cast来实现。具体有如下用法: a、将编译器执行的隐式转换显示化; b、或将void*转换为显式类型的指针; c、将算术值转换为枚举值; d、将基类(或基类指针/引用)转化为派生类(或派生类指针/引用) 其中,b、c、d存在潜在的危险;a存在潜在的数据损失。 3、reinterpret_cast 对操作数进行低级别的bit模式的重翻译,其正确性完全由编程者掌控,编译器不负任何责任。 推荐使用reinterpret_cast来实现所有指针的显示转换操作。 4、旧风格的显示转换语法: a、C++函数风格:type_name(expr) b、C语言风格:(type_name)expr 旧的显示转换风格,可以实现所有上述三种显示转换方式的功能。但由于其潜在的危险更难于跟踪,因此不推荐使用。 5、dynamic_cast ************************ 三、自定义类型转换 ************************** 自定义的类型转换有两种,一种是通过"类型转换函数" (hi.baidu.com/cosmicocean/blog/item/4b5e47af46f678fdfaed5038.html) 另一种是通过" 单参数的构造函数" 。 实际程序中,用户可以显示的指明某一个转换所采用的类型转换方式,若编译器允许这种转换(内置允许或用户自定义了该转换方式),则进行转换操作。用户没有显示指明时,编译器将根据的情况选择是否能进行隐式转换。下面阐述隐式转换相关的内容: 实际程序中,原类型需要转换为目标类型时,若有内置转换(lval->rval / promotion / standard conversion)则直接转换;否则,若类型转换函数转换的类型就是目标类型,则编译器会隐式的调用该函数进行转换;否则,编译器将结合用户自定义转换与标准转换序列,以达到目标类型。 最后一种情况实际上是如下形式的转换序列: Standard Conversion Sequence ->User-defined Conversion ->Standard Conversion Sequence (注意,序列中只能包含一个用户自定义的转换) 有时候,可以有不同的转换序列能实现原类型到目标类型的转换,编译器需要挑选出最好的一个序列进行隐式类型转换。 1、类型转换函数 含有类型转换函数的转换序列为:User-defined Conversion->Standard Conversion Sequence。 2、构造函数 含有构造函数的转换序列为:Standard Conversion Sequence->User-defined Conversion. 3、最佳选择 不论含有上述哪种用户自定义的转换,若有多个序列可以完成转换,标准转换序列的等级将决定选择那种转换;若几个序列优先级相同,则该转换为ambiguous,编译器无法完成转换。 |
联系客服