C/C++强制类型转换介绍

C/C++中的四种强制类型转换。

c中的强制类型转换
显式转换:
TYPE b = (TYPE) a;
隐式转换:

floag b=0.5;
int b=a; //向零取整

C++中兼容了C中的用法,并提供了4个强制转换类型关键字:

static_cast
const_cast
reinterpret_cast
dynamic_cast

1)static_cast
用法:

static_cast<type_id>(expression)

该关键字把expression的类型转换为type_id的类型,但没有运行时类型检查来保证转换的安全性。
主要用法:
(1)用于类层次结构中基类和子类之间指针或引用的转换。
上行转换:把一个(expression)从派生类转换为基类(安全)
下行转换:把一个(expression)从基类转换为炮声类(没有动态类型检查,不安全)
(2)用于基本数据类型的转换,int->char int->enum
(3)把空指针转换为目标类型的指针
(4)把任何类型表达式转换为void类型。

const auto a1=11;
const auto a2=4;

//C style
double res1=(double)(a1) / (double)(a2);

//c++ style
auto res2 = static_cast<double>(a1) / static_cast<double>(a2);

static_cast 不能转换掉const volitale关键字修饰的变量。

const int a=11;
const int *p;
const auto *res1 = static_cast<const int *>(p); //right
int *res2=static_cast<int *>(p); //error 
  1. const_cast

弥补1)static中不能转换const、volitale的不足,const_cast可以。
用法:

const_cast<type_i>(expression)
const int a=10;
const int *p=&a;
*p=20; //error
int res1 = const_cast<int>(a); //error
int res2 = const_cast<int *>(p);//right
//<>中必须是引用或指针,不能是实际变量

3)reinterpret_cast
用途:
1、改变指针或引用类型
2、将指针或引用转换为一个足够长度的整形。
3、将整形转换为指针或引用类型
用法:

reinterpret <type_id> (expression)
  1. dynamic_cast
    特点:
    1、上面三种都是在编译时完成的,dynamic_cast是在运行时完成的,运行时要进行类型检查
    2、不能用于基本数据类型的转换
    3、要求<>内的目标必须为指针或者引用。转换成功返回对应类型的指针,否则返回nullptr。
    4)上行转换时跟static_cast效果一样,下行转换时进行类型检查,比static_cast安全。
    5)使用dynamic_cast进行转换,基类中一定要有虚函数否则无法编译通过。由于运行时类型检查需要运行时类型信息,储存在类中的虚函数表中,因此必须定义了虚函数的类才有意义。
class A {
public:
	virtual void print(){
		cout << "in class A" << endl;
	};
};

class B :public A {
public:
	void print(){
		cout << "in class B" << endl;
	};
};

class C {
	void pp(){
		return;
	}
};

int main() {
	A *a1 = new B; // a1是A类型的指针指向一个B类型的对象
	A *a2 = new A; // a2是A类型的指针指向一个A类型的对象
	B *b1, *b2, *b3, *b4;
	C *c1, c2;
	b1 = dynamic_cast<B*>(a1);	// not null,向下转换成功,a1 之前指向的就是 B 类型的对象,所以可以转换成 B 类型的指针。
	if (b1 == nullptr) cout << "b1 is null" << endl;
	else               cout << "b1 is not null" << endl;

	b2 = dynamic_cast<B*>(a2);	// null,向下转换失败
	if (b2 == nullptr) cout << "b2 is null" << endl;
	else               cout << "b2 is not null" << endl;

	// 用 static_cast,Resharper C++ 会提示修改为 dynamic_cast
	b3 = static_cast<B*>(a1);	// not null
	if (b3 == nullptr) cout << "b3 is null" << endl;
	else               cout << "b3 is not null" << endl;

	b4 = static_cast<B*>(a2);	// not null
	if (b4 == nullptr) cout << "b4 is null" << endl;
	else               cout << "b4 is not null" << endl;

	a1->print();	// in class B
	a2->print();	// in class A
	
	b1->print();	// in class B
	// b2->print(); // null 引发异常
	b3->print();	// in class B
	b4->print();	// in class A

	c1 = dynamic_cast<C*>(a1);	// 结果为null,向下转换失败
	if (c1 == nullptr) cout << "c1 is null" << endl;
	else               cout << "c1 is not null" << endl;

	// c2 = static_cast<C*>(a1);	// 类型转换无效, Cannot cast from 'A*' to 'C*' via static_cast
	// delete 省略
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值