一、隐式类型转换:系统自动进行,不需要程序人员的介入
int m = 3 + 45.6;//48 把小数部分截掉,也属于隐式类型转换的一种行为。 double n = 3 + 45.6;//48.600000000000001
二、显式类型转换(强制类型转换)
int k = 5 % 3.2;//语法错误 int k = 5 % (int)3.2;//OK,C语言风格的强制类型转换 int k = 5 % int(3.2);//函数风格的强制类型转换,C语言也是
C++强制类型转换分为4种:我们现在写程序应该使用C++风格的强制类型转换:
这4种强制类型转换,分别用于不同的目的,每一个都又有一个不同的名字。提供4种类的目的:
提供更丰富的含义和功能,更好的类型检查机制,以及方便代码的书写和维护
a)static_cast
b)dynamic_cast
c)const_cast
d)reinterpret_cast
这四个强制类型转换都被称为“命名的强制类型转换(因为他们的每一个都有一个名字并且名字不相同)”
通用形式:
强制类型转换名<type>(express);
强制类型转换名,是上边的的,a,b,c,d四个名字之一。
type:转换的目标类型
express:你要转换的值(你要转换的是谁)
(2.1)static_cast:静态转换,大家就理解成“正常转换”,编译的时候就会进行类型转换检查
代码中要保证转换的安全性和正确性,static_cast含义跟C语言的强制类型转换这种感觉差不多
C语言风格的强制类型转换,以及编译器能够进行的隐式转换,都可以用static_cast类显式完成
可用于:
a)相关类型转换,比如整型和实型之间的转换
double f = 100.34f; int i = (int)f;//C语言风格的类型转换 int i1 = static_cast<int>(f);//C++风格的类型转换
b)后续学习类的时候类型转换成父类类型(继承关系),也能用这个static_cast转
class A{}; class B:public A{}; B b; A a = static_cast<A>(b);//把子类转成父类的对象。
c)void *与其他类型指针之间的转换,void* :无类型指针:可以指向任何类型的指针(万能指针)
int i = 100; int* p = &i; void* q =static_cast<int *>(p);//int *转成void *; int* db =static_cast<int*>(q);
不可用于:
a)一般不能用于指针类型之间的转换 比如:int*转double*,float*转double*等
double f = 100.0f; double* pf = &f; int *i=static_cast<int*>(pf);//不可以 float* fd = static_cast<float*>(pf);//不可以
(2.2)dynamic_cast:主要用来 运行时类型识别和检查。主要用来父类型和子类型之间的类型转换
(父类型指针指向子类型对象,然后用dynamic_cast把父指针类型转换往子指针类型转)
第三章第十节会详细讲解,dynamic_cast这里不多说
(2.3)const_cast:去除指针 或者引用的const属性。该转换能够将const性质去掉,编译时就会进行类型转换
const int ai = 90; int ai2 = const_cast<int>(ai);//不行,ai不是指针也不是引用无法转 const int* pai = &ai; int* pai2 = const_cast<int*>(pai);//语法正常 *pai2 = 120;//这种写值行为 是属于一种 未定义行为 。大家不要这么干 cout << ai << endl; cout << *pai << endl;//调试时ai=120 *pai=120但打印的时候90和120, //怪异行为*pai2=120;
(2.4)reinterpret_cast:编译的时候就会进行类型转换的检查
reinterpret_cast:重新解释。将操作数内容解释为另一种不同的类型(能把操作数的类型都转了)
处理无关类型的转换。也就是两个操作数类型之间没有关系。就等于可以乱转,自由转。怎么转都行,很随意。
常用于如下3种转换:
a)将一个整型(地址)转换成指针
int i = 10; int* p1 = &i; int* p2 = reinterpret_cast<int*>(&i); char* pc = reinterpret_cast<char*>(p1);
b)一种指针类型转换成另一种类型指针,按照转换后的内容重新解释内存的内容;
int i = 10; int* pi = &i; void* pvoid = reinterpret_cast<void*>(pi); int* pi2 = reinterpret_cast<int*>(pvoid); //被认为危险的类型转换,随便转怎么搞都行,编译器都不报错
c)也可以从一个指针类型转换为整型。
int iv1 = 100; long long lvl = 8888889889; int* piv1 = (int*)iv1;//C语言风格