【C++】C++四种类型转换方式

在C语言中我们使用了类型强转:

复制代码
int a = (int)b;

C++语言级别提供了四种类型转换方式。
为什么 C++ 需要四种类型转换

C 风格的转换格式很简单,但是有不少缺点的:

  1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
  2. 显式类型转换将所有情况混合在一起,代码不够清晰
    因此 C++ 提出了自己的类型转化风格,注意 因为 C++ 要兼容 C 语言,所以 C++ 中还可以使用 C 语言的
    转化风格

1.const_cast

去掉常量属性的一个类型转换。

cpp 复制代码
const int a = 10;

int *p1 = (int*)&a;

int *b = const_cast<int*>(&a);

const_cast<这里面必须是指针或者引用类型>

2.static_cast

提供编译器认为安全的类型转换。

我们使用百分之八九十的类型转换都是使用static_cast来进行类型转换的

几乎能做任何类型的转换,但是只能做编译器认为安全的类型转换。

cpp 复制代码
const int a = 10;
int* p1 = (int*)&a;
int* p2 = const_cast<int*>(&a);*/

/*int* p = nullptr;
double* p2 = static_cast<double*>(p);*/	// 这两个类型没有关联,无法进行类型转换
// int是四个字节,double是八个字节,转换后操作的内存变为八个,不安全。

基类类型 《=》 派生类类型,能不能用static_cast进行类型转换?

可以,基类和派生类有关联。

如果我们非要强制转换,我们可以使用reinterpret_cast来进行强制转换,但是这是不安全的。

3.reinterpret_cast

类似于C风格的强制类型转换(可能会不安全)。

4.dynamic_cast

主要用在继承结构中,可以支持RTTI类型识别的上下转换。

cpp 复制代码
#include <iostream>

class Base
{
public:
	virtual void func() = 0;
private:
};

class Derive1 : public Base
{
public:
	void func()
	{
		std::cout << "call Derive1::func" << std::endl;
	}
};

class Derive2 : public Base
{
public:
	void func()
	{
		std::cout << "call Derive2::func" << std::endl;
	}
	// Derive实现新功能的API接口函数
	void derive02func()
	{
		std::cout << "call Derive2::derive02func" << std::endl;
	}
};

void showFunc(Base* p)
{
	// dynamic_cast会检查p指针是否指向的是一个Derive2类型的对象
	// p -> vfptr -> vftable RTTI信息,如果是,dynamic_cast转换类型成功
	// 返回Derive2对象的地址,给pd2;否则返回nullptr
	Derive2* pd2 = dynamic_cast<Derive2*>(p);
	if (pd2 != nullptr)
	{
		pd2->derive02func();
	}
	else
	{
		p->func();	// 动态绑定		*p的类型 如果指向Derive2对象,调用derive02func函数
	}
}

int main()
{
	Derive1 d1;
	Derive2 d2;

	showFunc(&d1);
	showFunc(&d2);
	
	return 0;
}

dynamic_cast会检查p指针是否指向的是一个Derive2类型的对象

p -> vfptr -> vftable RTTI信息,如果是,dynamic_cast转换类型成功

返回Derive2对象的地址,给pd2;否则返回nullptr

static_cast也能进行,但是他会把所有的都转换成Derive2类型,如果要访问Derive2里面的成员变量,就会出错。
dynamic_cast 用于将一个父类对象的指针 / 引用转换为子类对象的指针或引用 ( 动态转换 )
向上转型:子类对象指针 / 引用 -> 父类指针 / 引用 ( 不需要转换,赋值兼容规则 )
向下转型:父类对象指针 / 引用 -> 子类指针 / 引用 ( dynamic_cast 转型是安全的 )
注意:
1. dynamic_cast 只能用于父类含有虚函数的类
2. dynamic_cast 会先检查是否能转换成功,能成功则转换,不能则返回 0

相关推荐
??tobenewyorker14 分钟前
力扣打卡第二十一天 中后遍历+中前遍历 构造二叉树
数据结构·c++·算法·leetcode
future141235 分钟前
每日问题总结
经验分享·笔记
rzl0241 分钟前
java web5(黑马)
java·开发语言·前端
时序数据说44 分钟前
为什么时序数据库IoTDB选择Java作为开发语言
java·大数据·开发语言·数据库·物联网·时序数据库·iotdb
jingling5551 小时前
面试版-前端开发核心知识
开发语言·前端·javascript·vue.js·面试·前端框架
我是小哪吒2.01 小时前
书籍推荐-《对抗机器学习:攻击面、防御机制与人工智能中的学习理论》
人工智能·深度学习·学习·机器学习·ai·语言模型·大模型
oioihoii1 小时前
C++11 forward_list 从基础到精通:原理、实践与性能优化
c++·性能优化·list
m0_687399841 小时前
写一个Ununtu C++ 程序,调用ffmpeg API, 来判断一个数字电影的视频文件mxf 是不是Jpeg2000?
开发语言·c++·ffmpeg
爱上语文1 小时前
Redis基础(5):Redis的Java客户端
java·开发语言·数据库·redis·后端
A~taoker1 小时前
taoker的项目维护(ng服务器)
java·开发语言