C++类型转换

隐试类型转换:

char c = 'A';
    int x = c;  //隐试类型转换
    cout << x << endl;

 

显式类型转换: 

//强制类型转换
    char c = 'A';
    int x = (int)c;  //C风格
    int y = int(c);//C++风格

 

C++扩展了四种操作符形式的转换:

static_cast:

static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换

①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
points.at<float>(index, 0) = static_cast<int>(bgr[0]);  //把int转换成float

 

③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性
    //1.静态类型转换:static_cast
    //语法:目标变量=static_cast<目标类型>(源类型变量);
    //适用场景:将void*指针转化为其它类型的指针
    int* pi = NULL;
    char c = long(pi);
    //强制类型转换这种不合理的转换可以通过
    
    //char c2= static_cast<long>(pi);
    //不合理的转换会报错--编译器会自动检查是否合理

    void* pv=pi;
    //pi = pv;  错误
    //void*不能隐试转换成其它类型的指针
    pi = static_cast<int*>(pv);//将void*转化为其它类型的指针

一个方向可以隐试转换,另一个方向就可以静态转换

 

 

 

 dynamic_cast

 

#include<iostream> 

//2.动态类型转换:dynamic_cast
    //语法:目标变量=dynamic_cast<目标类型>(源类型变量);
    //主要用于具有多态特性父子类指针或引用之间的显示类型转换

class A {
    virtual void func() {}
};
class B :public A {
    void func() {}
};
class C :public A {
    void func() {}
};


int main()
{
    B b;
    A* pa = &b;
    //B* pb = pa;  报错  向下造型直接转是不允许的

    //B* pb = static_cast<B*>(pa);  //合理转换
    //std::cout << "pa=" << pa << std::endl;
    //std::cout << "pb=" << pb << std::endl;

    //C* pc= static_cast<C*>(pa); //不合理--不报错
    //原因:指针指向的目标对象不一致
    //可是编译器认为从语法角度是合理的,编译成功,存在危险

    
    B* pb = dynamic_cast<B*>(pa);  //动态转换
    C* pc = dynamic_cast<C*>(pa);  //动态转换--不合理转换失败,返回NULL
    //不报错
    //会自动检查是否合理
    std::cout << "pa=" << pa << std::endl;
    std::cout << "pb=" << pb << std::endl;
    std::cout << "pc=" << pc << std::endl;
    if (pc == NULL) {
        std::cout << "转换失败"<< std::endl;
    }
            
    A& ra = b;
    //C& rc= dynamic_cast<C&>(ra);  //不合理的引用转换--抛出异常


    return 0;
}

 

 

   //3.去常类型转换:const_cast
    //语法:目标变量=const_cast<目标类型>(源类型变量);
    //目标类型 必须是指针
    //适用场景:主要用于去掉指针或引用的const属性
    volatile const int i = 100;
    //int* pi = &i;  错误,因为i是const,相当于常量,不能保存常量地址

    int* pi = const_cast<int*>(&i);    //通过const_cast的转换,去掉变量i的const属性后再赋值
    //注意:变量i还是有const属性
    *pi = 200;

    std::cout << "*pi=" << *pi << "," << "i=" << i << std::endl;
    /*
    特殊注意:
    const的变量值第一次读取后会放到寄存区里,以后都从寄存器里读取,这样执行效率高
    volatile的作用:使用该变量时,每次都从内存读取,而不是读取寄存器中的副本,这样保存const_cast转换后*pi的值和i的值相同
    如果没有volatile,由于i是const,它就从寄存器读取值100
    */

    std::cout << "pi=" << pi << "," << "&i=" << (int*)&i << std::endl;
    //&i=1  是编译器的错,把它转换成布尔类型了,强制类型转换一下就OK了

 

 

//4.重解释类型转换:reinterpret_cast
    //语法:目标变量=reinterpret_cast<目标类型>(源类型变量);
    //适用场景一:指针和整型数之间进行转换
    
    //int* p = 0x12345678;    错
    int* p= reinterpret_cast<int*>(0x12345678);//把整形数转换成地址

    //适用场景二:任意类型指针或引用之间转换
    char buf[] = "0001\00012345678\000123456";
    //"\000"-->'\0'
    struct A {
        char type[5];
        char id[9];
        char passwd[7];
    };

    A* a= reinterpret_cast<A*>(buf);//把数组变量转换成指针
    cout << a->type << endl;
    cout << a->id << endl;
    cout << a->passwd << endl;

 

 

 

 

 

posted @ 2020-08-10 10:17  天子骄龙  阅读(150)  评论(0编辑  收藏  举报