C++中的类型转换

        在C++语言中,类型转换分位两种:隐式类型转换 和 显式类型转换。

       1. 隐式类型转换

        隐式转换就是系统默认的、不需要加以声明就可以进行的转换。一般情况下,数据类型的转换通常是由编译系统自动进行的,不需要人工干预,所以被称为隐式类型转换。

      在以下四种情况下会进行隐式转换:

    1:算术运算式中,低类型能够转换为高类型。
    2:赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型;
    3:函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
    4:函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

int    itmp = 0;
double dtmp = 10;
dtmp = itmp;  //itmp被隐式转换为double
if(itmp);        //itmp被隐式转换为bool
itmp + dtmp;//计算结果被隐式转换为double

  

     2. 显示类型转换

     2.1旧式类型转换

旧式类型转换其实就是C风格转换,是从C语言中继承下来的,比如,为了转换一个类型为doubole的浮点数到整型:

int i;
double d;
i = (int)d;
或
int i;
double d;
i = int(d);

    2.2 C++新式类型转换

    上面两种方式不适用于C++中类(class)和类的指针,最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast, dynamic_cast。标准C++中有四个新式类型转换符:static_cast、dynamic_cast、reinterpret_cast、和 const_cast。

    dynamic_cast     

    dynamic_cast主要用于于对象的指针和引用。当用于多态类型时, 其将基类类型对象的引用或指针转换为同一继承层次中其他类型的引用和指针。

    dynamic_cast的转换格式:dynamic_cast< type> ( expression )

    该运算符把expression转换成type类型的对象。Type必须是类的指针、类的引用或者void*;如果type是类指针类型,那么expression也必须是一个指针,如果type是一个引用,那么expression也必须是一个引用。

    如果expression是type的基类,使用dynamic_cast进行转换时,在运行时就会检查expression是否真正的指向一个type类型的对象,如果是,则能进行正确的转换,获得对应的值;否则返回NULL,如果是引用,则在运行时就会抛出异常。例如:

class A  
{  
    virtual void f(){};  
};  
class B : public A  
{  
    virtual void f(){};  
};  
void main()  
{  
    A* pa = new B;    //
    A* pa2 = new A;  
    B* pb = dynamic_cast<B*>(pa);   // ok: pa actually points to a B  
    B* pb2 = dynamic_cast<B*>(pa2);   // pa2 points to a A not a B, now pa2 is NULL  
}

    static_cast

    static_cast的转换格式:static_cast< type > ( expression )

    该运算符把expression转换为type类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

   ①用于类层次结构中基类和子类之间指针或引用的转换。

    进行上行转换(把子类的指针或引用转换成基类表示)是安全的;

    进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。

   ②用于基本数据类型之间的转换。如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。

   ③把空指针转换成目标类型的空指针。

   ④把任何类型的表达式转换成void类型。

   注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

       reinpreter_cast

     reinpreter_cast的转换格式reinpreter_cast<type>(expression)    

      reinterpret_cast 是一种高度危险的转换,这种转换仅仅是对二进制位的重新解释。这个操作符能够在非相关的类型之间转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。例:

class A{};
class B{};
A* a = new A;
B* b = reinpreter_cast<B*> a;

        const_cast

         const_cast的转换格式:const_cast<type> (expression)

       该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type和expression的类型是一样的。常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

         

#include <iostream>  
using namespace std;  
class CA  
{  
public:  
    CA() :m_iA(10){}  
    int m_iA;  
};  
int main()  
{  
    const CA *pA = new CA;  
    // pA->m_iA = 100; // Error 此时通过pA对m_iA赋值会报错,因为const属性  
    CA *pB = const_cast<CA *>(pA);  
    pB->m_iA = 100;  
    // 现在pA和pB指向同一个对象,可以通过pB修改m_iA  
    cout << pA->m_iA << endl;  
    cout << pB->m_iA << endl;  
//-------------------------------------//
    const CA &a = *pA;  
    // a.m_iA = 200; // Error  
    CA &b = const_cast<CA &>(a);  
    b.m_iA = 200;  
    // 现在a和b都是同一个对象的引用,可以通过b修改m_iA  
    cout << b.m_iA << endl;  
    cout << a.m_iA << endl;  
}

猜你喜欢

转载自www.cnblogs.com/AlexBai/p/9156262.html