什么是强制类型转换?
强制类型转换,是指显式地把一种类型的对象转换为另一种类型的行为。强制类型转换是危险的行为,但有时候我们又不得不使用强制类型转换。比如,分子分母为整数,但希望执行浮点数除法时,就需要把分子或分母强制转换成浮点数。
int a=1;
int b=2;
double c=(double)a/b;
旧式的强制类型
C风格的强制类型转换
C语言的强制类型转换格式如下:
(type)expression;
type是要强制转换的目标类型,express是被转换的对象,如:
(double)a;
(int)b;
函数风格的强制类型转换
和C风格大同小异,格式如下:
type(expression);
type是要强制转换的目标类型,express是被转换的对象,如:
double(a+c);
int(3.4*b);
C++的强制类型转换
C++的强制类型转换分为4种:static_cast,const_cast,reinterpret_cast和dynamic_cast。本文只介绍前3种强制类型转换。
C++的强制类型转换格式如下:
cast-name<type>(expression);
cast-name是static_cast,const_cast,reinterpret_cast和dynamic_cast中的一种,type是要强制转换的目标类型,express是被转换的对象。
static_cast
直译成中文就是“静态转换”,static_cast用于具有明确定义的类型转换。
int a=2;
double b=static_cast<double>(a);//把a强制转换为浮点数2.0
int c=static_cast<int>(2.5);//把2.5强制转换为整数2
static_cast不能执行没有定义的类型转换。
int*a=new int(2);
double*b=static_cast<double*>(a);//错误!企图将int*类型强制转换为double*类型
能通过隐式转换完成的类型转换,都可以通过static_cast完成。
const_cast
const_cast的功能就和它的名字一样,只能改变const修饰符。我们无法更改const指针指向的对象,但一定要执行更改操作时,就需要使用const_cast。
int a=0;
const int*b=&a;
*b=1;
这是一段错误的代码,b是const指针,无法通过间接访问修改a的值。
int a=0;
const int*b=&a;
int*c=const_cast<int*>(b);
*c=1;
原本const int* 类型无法为int* 类型赋值,但可以通过const_cast将const int* 类型强制转换为int* 类型,实际上这也是const_cast较多的用法。
对const指针使用const_cast时,需要特别注意的是,如果运算对象为底层const的话,通过指针执行写操作是未定义行为。不要试图抹去const指针的限定符,从而修改底层const对象的值!
const int a=0;
const int*p=&a;
int*b=const_cast<int*>(p);
*b=1;
这段代码试图通过int*b更改const int a的值,这种类似“洗钱”的行为可能造成严重隐患,并且编译器不会察觉!
const_cast只能修改指针和引用的const修饰符。
const int a=0;
int b=const_cast<int>(a);//错误!const_cast中的类型必须是指针或引用
除此之外,const_cast还不能修改基础类型。
int*a=new int(0);
double*b=const_cast<double*>b;//错误!试图修改int*a的基础类型为double*
如果一定要修改基础类型,则需要下面的类型来实现。
reinterpret_cast
interpret是“解释”,reinterpret就是“重解释”。和它的名字一样,reinterpret_cast会重新解释强制转换的对象,但这种解释是低级的。使用reinterpret_cast没有太多限制,这使得retinterpret_cast十分危险。
char*a = new char('a');
double*b=reinterpret_cast<double*>(a);
这段看似荒唐的代码,实际上是可以编译通过的,double*类型的指针指向的对象实际上是int类型,这可能引起严重的错误,并且编译器不会察觉!
实际上,旧式强制类型转换和static_cast,const_cast和reinterpret_cast相似,如果static_cast或const_cast能成功转换表达式,则使用前两种方式,否则将执行reinterpret_cast。
写在最后
强制类型转换是程序员显式声明的类型转换,所以编译器不会警告,因此应当谨慎使用。
文章有任何错误欢迎在评论区指出。
转载:https://blog.csdn.net/m0_55464171/article/details/115643928