C++类型转化
引入C++的类型转化前,先介绍C语言的类型转化
什么是类型转化
如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化
它又分为两类:隐式类型转化/显示类型转化
1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
2. 显式类型转化:需要用户自己处理
int main()
{
double b = 11.12;
int a = b;
cout << a << endl;
return 0;
}
上面就是隐式类型转化,
int main()
{
int a = 10;
int* p = (int*)a;
int *p1 = &a;
int p2 = (int)p1;
cout << p << endl;
return 0;
}
上面的就是显示类型转化。
缺陷:1.类型转化时都是用相似形式写,导致可视性差,难以发现哪些类型转化错误
2. 当我们的doule转化成int的时候,会出现数据精度丢失的情况。
3.显示类型将转化的所有情况都混合在一起,,导致代码不够清晰
对此,C++又添加了一些属于C++风格的类型转化,同时还兼容C语言的类型转化。
C++类型转化:
总概:
static_cast
reinterpret_cast
const_cast
dynamic_cast
在此之前我们先来讲解一下关于整形提升的问题:
整形提升
是什么?
1.整形提升(Integral Promotion)是C/C++中的一种隐式类型转换规则,指将尺寸小于 int 的整型(如 char 、 signed char 、 unsigned char 、 short 、 unsigned short )自动转换为 int 或 unsigned int 类型,以进行运算或函数调用。
目的:
避免小尺寸整型在运算时因字节数不足导致精度丢失或溢出,统一运算时的类型宽度,保证计算结果的准确性。
举例:
当小尺寸整型参与算术运算(如 + 、 - 、 * 、 / 、比较等)时,会先被提升为 int (若 int 能容纳该类型的所有取值,则提升为 int ;否则提升为 unsigned int )。
char类型最大是256 char a=100.b=200; char c=a+b;
当小尺寸整型作为实参传递给无显式原型的函数,或传递给参数为“可变参数”的函数(如 printf )时,会被自动提升为 int 或 unsigned int 。
char ch='A'; printf("%c",ch);
static_cast(相关类型)
static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换


reinterpret_cast(不相关类型)
reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型
对于上图,我们使用static_cast发现编译不过,使用reinterpret_cast

const_cast
const_cast最常用的用途就是删除变量的const属性,方便赋值
ps:
1.仅可用于指针或引用类型
2.若原始变量本身是 const 类型(如 const int a = 5; ),通过 const_cast 强制修改其值,结果是未定义的(可能崩溃、值不改变等)。
3.仅当变量本身非 const ,但被 const 指针/引用指向时(如 int a = 5; const int* p = &a; ),才可安全通过 const_cast 移除 const 并修改变量值。
4.
dynamic_cast
dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
注意:
1. dynamic_cast只能用于父类含有虚函数的类
2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0

A a 非空地址(如 00000004F6C76FAA8 ) 0 (空指针)
static_cast 不做运行时类型检查,强制转换;
dynamic_cast 检测到 a 实际是 A 类型,无法转换为 B* ,返回空指针
3. 两种转换的区别
- static_cast :在编译时进行类型转换,不做运行时检查,若转换逻辑错误(如将 A 对象转换为 B* ),编译不会报错,但运行时可能出现未定义行为。- dynamic_cast :在运行时进行类型检查(依赖虚函数表),若转换不合法(如基类对象转派生类指针),返回空指针;若合法,返回正确的派生类指针。它是处理多态类型安全转换的重要方式。
因此:应谨慎使用强行转化。
边角料:
变长数组
const int n = 5; int a[n];
const int n=10;
1.n不是常量,而是常变量,它是开了空间的。
2.n可以间接修改,但不可以直接修改。是通过指针间接可以修改,但是访问n的时候还是不变。
因为编译器认为const常变量不能直接被修改的,所有编译器作了一个优化:不去内存那里去取,而是取寄存器那里。那么,转化又是有安全隐患的,所以有了volatile。
volatile:告诉编译器,每次都要取内存那里取,(不能直接进行替代),再把它放到寄存器那里。
好了,关于类型转化的内容就到处结束了,希望大家都一起进步。
最后到了本次鸡汤环节:
在这看似萧瑟的枝桠间,月亮仍在绽放光芒;就像人生的低谷里,你我的坚持也终会成为照亮前路的光。别因暂时的荒芜停下脚步,那些扎根的坚韧,终会在某一天,让你枝繁叶茂,触摸到属于自己的圆满。
更多推荐







所有评论(0)