C++ 4种类型转换运算符

    C语言中的强制转换在C++中对基础数据类型也是适用的,但是对于类对象就不够严格。于是C++中增加了4种类型转换运算符,使得转换过程更规范:
dynamic_cast;
const_cast;
static_cast;
reinterpret_cast;

1、dynamic_cast动态类型转换
    dynamic_cast是运行时的类型转换,可在基类和派生类之间进行类型转换,并且能够检查类型是否符合转换。它不能回答“指针指向的是哪类对象”的问题,但可以回答“是否可以安全地将对象的地址赋给特定类型的指针”的问题。 dynamic_cast运算符的语法如下:

dynamic_cast< type-name > (expression);

    该运算符的用途是,使得能够在类层次结构中进行向上转换(由于is-a关系,这样的类转换是安全的),而不允许其他转换。
假设High和Low是两个类,而ph和pl是的类型是High * 和 Low ,则仅当Low是High的可访问基类(直接或间接)时,下面的语句才将一个Low 指针赋给pl:

pl = dynamic_cast<Low *>ph;//派生类指针通过dynamic_cast转为基类指针赋给基类指针;

如果Low不是High的可访问基类,上述语句将空指针赋给pl

2、const_cast
    const_cast运算符用于执行只有一种用途的类型转换,及改变值为const或volatitle,其语法与dynamic_cast运算符相同

const_cast < type-name > (expression)

    如果类型的其他方面也被修改,则上述类型转换将出错。也就是说,除了const 或volatitle特征(或有无)可以不同,type-name和expression的类型必须相同。再次假设High和Low是两个类:

High bar;
const High * pbar = &bar;
...
High * pb = const_cast< High * >pbar;//valid   type-name和expression只是const属性不同
const Low * pl = const_cast< Low * >(pbar);//invalid  type-name为Low*;expression为const High *

const_cast不是万能的。它可以修改执行一个值的指针,但修改const值的结果是不确定的。

3、static_cast:静态类型转换
    static_cast是在编译时进行类型转换,只能用于已知的类型之间的转换。主要用于基本数据类型的转换、隐式转换的显式化和向上转换(子类指针或引用转为父类指针或引用)。static_cast运算符的语法与其他类型转换运算符相同:

static_cast < type-name > (expression);

    仅当type-name 可被隐式转换为expression所属的类型或expression可被隐式转换为type-name所属的类型时,上述转换才合法。 假设High是Low的基类,而Pond是一个无关的类,则从High类到Low类的转换,从Low到High的转换都是合法的,而从Low到Pond的转换是不允许的。

High bar;
Low blow;
...
High * pb = static_cast< High * >(&blow);//valid upcast
Low * pl = static_cast< Low * >( &bar);//valid downcast
Pond *pmer = static_cast< Pond *>(&blow);//invalid, Pond unrelated

    第一种转换是合法的,因为向上的转化可以显式的进行。第二种转换是从基类指针到派生类指针,在不进行显式转换的情况下,将无法进行。
4、reinterpret_cast
    reinterpret_cast运算符用于天生危险的类型转换。它不允许删除const,但会执行其他令人生厌的操作。语法与另外3个相同:

reinterpret_cast< type-name >(expression);

下面是一个使用示例:

struct dat{short a; short b;};
long value = 0xA224B118;
dat * pd = reinterpret_cast< dat * >(&value);
cout<<hex<< pd->a;//display first 2 bytes of value

    通常这样的转换适用于依赖于实现的底层技术,是不可移植。例如,在不同系统在存储多字节整型时,可能以不同的顺序存储其中的字节。
    然而,reinterpret_cast运算符并不支持所有的类型准换。例如,可以将指针类型转换为足以存储指针表示的整型,但不能将指针转换为更小的整型或浮点型。另一个限制是,不能将函数指针转换为数据指针。

总结:
1、派生类指针或引用可以直接赋给基类指针(可以理解为把派生类切割了赋给基类),也可以使用static_cast对指针进行转换。
2、基类指针或引用可以使用dynamic_cast,或static_cast转换为派生类指针或引用。
3、static_cast可以用于基本类型之间的转换,dynamic_cast不可以
4、static_cast可以在基本类型指针与void *之间做转换,dynamic_cast
5、static_cast和dynamic_cast都不能在基本类型指针或引用剪做转换
6、const_cast运算符主要用于增加或减少指针的const修饰,指针指向的内容为非const,则可以用指针修改指向的内容;如果指针指向的内容本身就是const值,通过指针方式也不能修改指向的内容。
7、reinterpret_cast可以将指针类型转换为足以存储指针表示的整型,但不能转换为更小的整型或浮点型(转换为不足以存储指针表示的整型的行为是不允许的);不能将函数指针转换为数据指针。
注:使用dynamic_cast转换后一定要对指针判空。指针为空,表示转换失败;指针非空,表示转换成功。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值