【C/C++学习笔记】强制转换

C、C++强制转换说明

介绍说明

1. 使用C风格的强制类型转换

char ch = 'a';
int a = (int)ch;

2. 使用标准C++的类型转换符:static_cast,  dynamic_cast。标准C++中有四个类型转换符:static_castdynamic_castreinterpret_cast、和const_cast。

关键字说明
static_cast 用于良性转换,一般不会导致意外发生,风险很低
const_cast用于 const 与非 const、volatile 与非 volatile 之间的转换
reinterpret_cast高度危险的转换,这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换
dynamic_cast借助 RTTI,用于类型安全的向下转型(Downcasting)

示例:
static_cast< new_type >(expression)

const_cast< new_type >(expression)

reinterpret_cast < new_type >(expression)

dynamic_cast< new_type >(expression)

备注new_type为目标数据类型,expression为原始数据类型变量或者表达式。 

(1) static_cast

①static_cast 用于基本数据类型之间的转换,不执行运行时类型检查,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
②static_cast 把任何类型的表达式转换成void类型。,例如char *转void *等;
③static_cast 把void指针转换成目标类型的指针(不安全!!),例如void *转int *等;
④static_cast 用于非多态类型的转换。
④static_cast 用于有转换构造函数或者类型转换函数的类与其它类型之间的转换(用于类层次结构中基类和子类之间指针或引用的转换)
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。

注意:

①static_cast不能转换掉expression的const、volitale、或者__unaligned属性。
②static_cast 不能用于无关类型之间的转换,因为这些转换都是有风险的,例如:
 两个具体类型指针之间的转换,例如int *转double *、Student *转int *等。
 int 和指针之间的转换。将一个具体的地址赋值给指针变量是非常危险的,因为该地址上的内存可能没有分配,也可能没有读写权限,恰好是可用内存反而是小概率事件。
③static_cast 是“静态转换”的意思,也就是在编译期间转换,转换失败的话会抛出一个编译错误。

(2)  dynamic_cast

①dynamic_cast 用于多态类型的转换。
②dynamic_cast 用于在类的继承层次之间进行类型转换,主要用于类层次间的上行转换(Upcasting)和下行转换(Downcasting),以及类之间的交叉转换(cross cast)。向上转型是无条件的,与static_cast一样,不会进行任何检测,所以都能成功;向下转型的前提必须是安全的,dynamic_cast 要借助 RTTI 进行检测,所有只有一部分能成功。
③dynamic_cast 与 static_cast 是相对的,dynamic_cast 是“动态转换”的意思,static_cast 是“静态转换”的意思。dynamic_cast 会在程序运行期间借助 RTTI 进行类型转换,这就要求基类必须包含虚函数;static_cast 在编译期间完成类型转换,能够更加及时地发现错误。
④dynamic_cast 的语法格式为:  dynamic_cast <newType> (expression)
  newType 和 expression 必须同时是指针类型(包含void *)或者引用类型。换句话说,dynamic_cast 只能转换指针类型和引用类型,其它类型(int、double、数组、类、结构体等)都不行。
  运行时类型检查,对于指针,如果转换失败将返回 NULL;对于引用,如果转换失败将抛出std::bad_cast异常。
⑤bad_cast :dynamic_cast 运算符强制转换为引用类型失败,会引发 bad_cast 异常。

try {
	Circle& ref_circle = dynamic_cast<Circle&>(ref_shape); 
}
catch (bad_cast b) { 
	cout << "Caught: " << b.what(); 
}

注意:尽量少使用转型操作,尤其是dynamic_cast 会进行类型检查,耗时较高,会导致性能的下降,尽量使用其他方法替代。

(3) const_cast:
  const_cast 比较好理解,它用来去掉表达式的const、volitale、或者__unaligned属性。换句话说,const_cast 就是用来将 const/volatile/__unaligned 类型转换为非 const/volatile/__unaligned 类型,例如将 const int 类型转化为 int。

(4) reinterpret_cast:
  ① reinterpret_cast 这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,非常简单粗暴,所以风险很高。
  ② reinterpret_cast 可以认为是 static_cast 的一种补充,一些 static_cast 不能完成的转换,就可以用 reinterpret_cast 来完成,例如两个具体类型指针之间的转换、int 和指针之间的转换(有些编译器只允许 int 转指针,不允许反过来)。
③ 允许将任何指针转换为任何其他指针类型(但其本身并不安全)
④ reinterpret_cast 的一个实际用途是在哈希函数中,即,通过让两个不同的值几乎不以相同的索引结尾的方式将值映射到索引。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值