目录
1.隐式类型转换和强制类型转换
2.隐式类型转换带来的危险
3.c++提供的标准类型转换关键字
4.总结
1.隐式类型转换和强制类型转换
c语言的类型转换可以分为隐式类型转换和强制类型转换。
#include<iostream>
using namespace std;
int main()
{
	double a = 3.14;
	int b = a; 
	cout << b << endl;
	int* p = &b;
	int pp = (int)p;
	cout << pp << endl;
	return 0;
} 
这里的转换的前提都是这两个类型意义相近。

ps:要区别继承中的切割和隐式类型转换。
class A
{
public:
	A()
	:_a(0)
	{}
private:
	int _a;
};
class B :public A //继承A
{
public:
	B()
	:_b(0)
	,A()
	{}
private:
	int _b;
};
int main()
{
	B b;
	A a = b;//一种原生支持的切割
	return 0;
} 
我们要知道隐式类型转换的共性是要生成一个临时对象,明显将b赋值给a的时候不会产生临时对象。只需要将这种方式作为编译器支持的原生方式转换就好。
2.隐式类型转换带来的危险
#include<iostream>
using namespace std;
void Move(size_t pos)
{
	int end = 4;
	while (end >= pos) //发生了隐式类型转换,将int的end转换成了size_t无符号数
	{
		//arr[end + 1] = arr[end]; 向后挪
		end--;
	}
}
int main()
{
	Move(0);
	return 0;
} 
这段程序死循环了。
原因是:当end减到-1才应该退出循环,但是因为end和pos在表达式的两边。且两个数意义相近
,因此end变成了无符号数,-1就变成了整形的最大值(要了解负数补码和无符号数的定义)。
end突然搞那么大,就必然跑不出去了奥。
3.c++提供的标准类型转换关键字
a.static_cast<T>
和隐式类型转换一样。

问题:不支持类型差距太大的转换

b.reinterpret_cast<T>

问题: 不支持去除const属性
 
c.const_cast
常用来给const变量赋值(去除const属性):
    const int a = 3;
	int* pp = const_cast<int*>(&a);
	*pp = 4;
	cout << a << endl; 
这里有一个奇怪的现象:

显示的结果为a的值依然是3,再通过调试看看内存中a的值:
 
太神奇了,内存中显示a是4诶。
实际上,这和ide的处理有关,在vs环境下const变量并不是存于常量区中。而是存在一个特殊寄存器中,本质也在栈中。调用时,内存中的const变量就算在内存中发生了变化,但由于已经被寄存器将之前的值读出了,所以我们看见的结果没有发生变化。
d.dynamic_cast
dynamic_cast用于父子类的向下赋值,向上赋值原生支持(切割)。
class A
{
public:
	virtual void f() {}
};
class B : public A	//继承A
{};
void fun(A* pa)
{
	// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回。
	B* pb = dynamic_cast<B*>(pa);
    //转换为B*(子类)
	if (pb)
	{
		cout << "转换成功" << endl;
	}
	else
	{
		cout << "转换失败" << endl;
	}
}
int main()
{
	A a;	B b;
	fun(&a);
	fun(&b);
} 

若是传入A(父类),是一种不安全的转换(可能存在越界问题)。
看图:

4.总结
建议使用c++提供的指定类型转换关键字,这种方式更加安全。可以避免隐式类型转换的坑,并且还提供了dynamic_cast和const_cast来处理特殊问题。


![[附源码]计算机毕业设计springboot高校学生摄影作品展示平台](https://img-blog.csdnimg.cn/72ee6c7b7bac4876b608f6b112b741ee.png)




![[附源码]SSM计算机毕业设计校园征兵及退役复原管理系统JAVA](https://img-blog.csdnimg.cn/d49e0e3d68fc4550a3c7c8d3e9e6ed40.png)











