C++的强制类型转换

隐式类型转化:相关类型的转换,即意义相似的类型。
强制类型转化:不相关类型的转换,比如:指针和整型.

static_cast

用法:static_cast<类型说明符> (变量或表达式)

作用:显式、静态地执行隐式类型转换和用户定义的转换,不进行运行时检查。

分类:

  1. 用于基本类型数据的转换
	float a = 2.3;
	int b = static_cast<int>(a);
  1. 把空指针转换成目标类型的空指针
  2. 把任何类型的表达式转换为void类型
  3. 父类指针/引用到子类指针/引用的转换,是不安全的
class A
{
public:
	A() {}
};

class B : public A
{
public:
	B() {}
};

void test()
{
	//父类指针到子类指针的转换,不安全
	A* a = new A;
	B* b = static_cast<B*> (a);
}

注意:static_cast只能在有相互联系的类型中进行相互转换,不相关类型是不可以转换的。

int a = 10;
int *b = static_cast<int*>(a); //a为整形,转为int*是不可以的

整形和指针属于两种完全不同的类型,所以是不可以通过static_cast转换。

reinterpret_cast

作用:不相关类型的转换(相当于C语言中的强转)

int a = 10;
int *b = reinterpret_cast<int*>(a);

const_cast

const_cast最常用的用途就是删除变量的const属性,方便赋值

const int a = 10;
int *p = const_cast<int*>(&a);

但是,const_cast是不能用来执行任何类型的转换的,这样都会引起编译错误的!

const char t = 'a';
int *p = const_cast<int*>(&t); //编译错误

const_cast只能调节类型限定符,不能更改基础类型。

下面我们来看一段代码:

	const int a = 10;
	int *p = const_cast<int*>(&a);
	*p = 20;
	cout << "a: " << a << endl;
	cout << "*p: " << *p << endl;

我们预期的结果,a为20,*p也为20。打印结果:
在这里插入图片描述在这里插入图片描述在内存中,a已经改为20,但是打印确实10。其实是编译器在这里玩了个小聪明,const int a=10,编译器认为a就不会发生改变了,所以就把a放在了寄存器中,因为访问寄存器要比访问内存单元快的多,每次都从寄存器中取数据,但是后来a在内存中发生变化后,寄存器中的数据没有发生变化,所以打印的是寄存器中的数据。

可以通过volatile关键字这个问题。当要求使用volatile声明变量值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。避免过度优化。

	volatile const int a = 10;
	int *p = const_cast<int*>(&a);
	*p = 20;
	cout << "a: " << a << endl;
	cout << "*p: " << *p << endl;

在这里插入图片描述
在写代码的过程中要注意这个问题。

dynamic_cast

多态场景下用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)

向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)

向下转型:父类对象指针/引用- >子类指针/引用(用dynamic_cast转型是安全的)

注意:

  • dynamic_cast只能用于含有虚函数的类
  • dynamic_cast在运行期强制转换,运行时进行类型检查,若安全,才会转化成功。
  • 对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针。
  • 对引用进行dynamic_cast,失败抛出一个异常bad_cast,成功返回正常cast后的对象引用。
  • 不能用于内置的基本数据类型的强制转换。
class A
{
public:
	virtual void fun() {}
};

class B : public A
{
};

void test()
{
	A* pb = new A;
	B* pb2 = static_cast<B*> (pb);
	B* pb3 = dynamic_cast<B*>(pb);
	cout << pb2 << endl;
	cout << pb3 << endl;

	pb = new B;
	pb2 = static_cast<B*> (pb);
	pb3 = dynamic_cast<B*>(pb);
	cout << pb2 << endl;
	cout << pb3 << endl;
}

在这里插入图片描述
总结:

  • 去const属性用const_cast
  • 基本类型转换用static_cast
  • 多态类之间的类型转换用daynamic_cast
  • 不同类型的指针类型转换用reinterpreter_cast
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值