引入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:告诉编译器,每次都要取内存那里取,(不能直接进行替代),再把它放到寄存器那里。

好了,关于类型转化的内容就到处结束了,希望大家都一起进步。

最后到了本次鸡汤环节:

在这看似萧瑟的枝桠间,月亮仍在绽放光芒;就像人生的低谷里,你我的坚持也终会成为照亮前路的光。别因暂时的荒芜停下脚步,那些扎根的坚韧,终会在某一天,让你枝繁叶茂,触摸到属于自己的圆满。

更多推荐