C++四种强制类型转换

static_cast

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

  • 用于基本类型数据的转换
double  d = 3.1222;
int a = static_cast<int> (d);
  • 把空指针转换成目标类型的空指针
  • 把任何类型的表达式转换为void类型
  • 用于类层次结构中基类和派生类之间指针或引用的转换
    进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
    进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。

举例:

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

class  C {};

int main()
{
	A* pa = new A;
	B* pb;
	C* pc;
	pb = static_cast<B*>(pa);//基类指针转换为派生类指针
	pc = static_cast<C*>(pa);//报错,C类与A类无关
	return 0;

}

注意:

  • static_cast不能转换掉expression的const、volitale或者__unaligned属性。
  • static_cast只能在有相互联系的类型中进行相互转换
  • 在编译期强制转换。

const_cast

用法:const_cast<type_id> (expression)
作用:去掉类型的const或volatile属性

  • 常量指针被转化成非常量指针,并且仍然指向原来的对象
const Base* bp = new Base;
Base* dp = const_cast<Base*>(bp);//不安全
  • 常量引用被转换成非常量引用,并且仍然指向原来的对象
  • 常量对象被转换成非常量对象。

举例:

#include<iostream>
int main()
{
	const int ma = 10;
	int& mb = const_cast<int&>(ma);
	int* ptr = const_cast<int*>(&ma);
	mb = 20;//未定义行为
	cout << "ma=" << ma << " " << "mb=" << mb << " " << "*ptr=" << *ptr << endl;

	*ptr = 30;//未定义行为
	cout << "ma="<<ma << " " << "mb="<<mb << " " << "*ptr="<<*ptr << endl;
	
	return 0;


}

在这里插入图片描述
未定义行为:未定义行为是指C语言标准未做规定的行为。编译器可能不会报错,但是这些行为编译器会自行处理,所以不同的编译器会出现不同的结果,什么都有可能发生,这是一个极大的隐患,所以我们应该尽量避免这种情况的发生。

注意

  • const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。
  • const_cast是不能用来执行任何类型的转换的(const_cast只能调节类型限定符,不能更改基础类型)

reinterpret_cast

用法:reinterpret_cast<type_id> (expression)
作用:不相关类型的转换(相当于C语言中的强转)

  • 改变指针或引用的类型
  • 将指针或引用转换为一个足够长度的整形
  • 将整型转换为指针或引用类型。

举例:

#include<iostream>
int main()
{
	int a = 10;
	int* pa = &a;
	long b = reinterpret_cast<long>(pa);//把一个指针转换为一个整数,取出地址值
	long* pb = reinterpret_cast<long*>(pa);//int *==>long *

	cout << "*pa=" << *pa << endl;
	cout << "b=" << hex << b << endl;
	cout << "pa=" << pa << endl;
	cout << "pb=" << pb << endl;

	return 0;


}

在这里插入图片描述

dynamic_cast

用法:dynamic_cast<type_id> (expression) type-id必须是类指针,类引用或者void*

作用:用于将一个父类的指针或引用转化为子类的指针或引用(安全的向下转型

  • 基类指针所指对象是派生类对象,这种转换是安全的
  • 基类指针所指对象为基类对象,转换失败,返回结果为0

举例:

class Base
{
public:
	Base() {};
	virtual void show() { cout << "Base\n"; }
};

class Derive :public  Base
{
public:
	Derive() {};
	virtual void  show() { cout << "Derive\n"; }
};

int main()
{
	Base* base = new Derive;
	if (Derive * ptr1 = dynamic_cast<Derive*>(base))
	{
		cout << "转换成功" << endl;
		ptr1->show();
		cout << endl;
	}

	base = new Base;
	if (Derive * ptr2 = dynamic_cast<Derive*>(base))
	{
		cout << "转换成功" << endl;
		ptr2->show();
		cout << endl;
	}
	else
	{
		cout << "转换失败" << endl;
	}
	
	delete(base);
	return 0;
}

在这里插入图片描述
注意:

  • 对于类的dynamic_cast转换,基类中一定要有虚函数,否则编译不通过。
  • 对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针。
  • 对引用进行dynamic_cast,失败抛出一个异常bad_cast,成功返回正常cast后的对象引用。
  • dynamic_cast在运行期强制转换,运行时进行类型检查,较安全。
  • 不能用于内置的基本数据类型的强制转换。

总结

在这里插入图片描述

  • 12
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值