C++中的类型转换之 const_cast static_cast dynamic_cast reinterpret_cast

1 简介

        C++是一种面向对象的语言,面向对象的三大特点是,封装、继承和多态。要想很好的使用面向对象的多态,就一定要使用指针和引用,而在使用指针和引用的过程中必然会碰到类型的转换。C++的类型转换分为,隐式转换和显示转换,本文主要讨论C++中的四种显示转换运算符,

  • const_cast <new_type> (expression)
  • static_cast <new_type> (expression)
  • reinterpret_cast <new_type> (expression)
  • dynamic_cast <new_type> (expression)

2 const_cast <new_type> (expression)

        const_cast <new_type> (expression),用于移除变量的const或者volatile的限定。去除变量const限定并不是为了修改const变量的值,而是当我们调用一个参数不是const的函数,而实际传入的参数却是const时,使用const _cast去除const限定,以便函数能够接受这个实际参数。


3 static_cast <new_type> (expression)

        static_cast <new_type> (expression),没有运行时类型检查来保证转换的安全性。

为什么需要static_cast强制转换?

  • 情况1:void指针->其他类型指针
  • 情况2:改变通常的标准转换
  • 情况3:避免出现可能多种转换的歧义

主要用途:

  • 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
  • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • 把void指针转换成目标类型的指针(不安全!!)
  • 把任何类型的表达式转换成void类型。
        注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。


4 dynamic_cast <new_type> (expression)

        dynamic_cast <new_type> (expression),把expression转换成new_type类型,new_type必须是类的指针、类的引用或者void*。若new_type是类的指针,则expression也必须是类的指针;若new_type是类的引用,则expression也必须是类的引用。

为什么需要dynamic_cast强制转换?

主要用途:

  • 在类层次间进行上行转换(子类转化的基类),此时dynamic_cast效果等同static_cast
  • 在类层次间进行下行转换(基类转换到子类),dynamic_cast转换时会进行类型检测,比static_cast更安全
  • 在类之间进行交叉转换(cross cast)

实例

        dynamic_cast和static_cast进行上下行转换实例

class Base
{
public:
    int m_iNum;
    virtual void foo();
};

class Derived:public Base
{
public:
    char *m_szName[100];
};

void func(Base *pb)
{
    Derived *pd1 = static_cast<Derived *>(pb);

    Derived *pd2 = dynamic_cast<Derived *>(pb);
}
        在上面的代码段中,
        如果pb实际指向一个Derived类型的对象,pd1和pd2是一样的,并且对这两个指针执行Derived类型的任何操作都是安全的;
        如果pb实际指向的是一个Base类型的对象,那么pd1将是一个指向该对象的指针,对它进行Derived类型的操作将是不安全的(如访问m_szName),而pd2将是一个空指针(即0,因为dynamic_cast失败)。
        注意:Base要有虚函数,否则会编译出错;static_cast则没有这个限制。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类 的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。


5 reinterpret_cast <new_type> (expression)

        reinterpret_cast <new_type> (expression),new_type必须是一个指针、引用、算数类型、函数指针或者成员指针。该运算符主要用于处理无关类型的转换;它会产生一个新的值,这个值会有与原始参数(expression)完全相同的比特位。

IBM的C++指南里,说明的reinterpret_cast的用途:

  • 从指针类型到一个足够大的整数类型
  • 从整数类型或者枚举类型到指针类型
  • 从一个指向函数的指针到另一个不同类型的指向函数的指针
  • 从一个指向对象的指针到另一个不同类型的指向对象的指针
  • 从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针
  • 从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针

        注意:操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换;reinterpret_cast是为了映射到一个完全不同类型的意思,需要把类型映射回原有类型时用到它。

6 参考

const_cast, http://www.cnblogs.com/ider/archive/2011/07/22/cpp_cast_operator_part2.html

stati_cast,http://www.cnblogs.com/ider/archive/2011/07/31/cpp_cast_operator_part4.html

dynamic_cast,http://www.cnblogs.com/ider/archive/2011/08/01/cpp_cast_operator_part5.html

reinterpret_cast,http://www.cnblogs.com/ider/archive/2011/07/30/cpp_cast_operator_part3.html

C++中类型转换探讨,http://www.360doc.com/content/11/0123/19/59141_88548674.shtml

Inside C++ Object model


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值