zoukankan      html  css  js  c++  java
  • C++下的强制转换类型

    一、static_cast

       static_cast,静态类型转换。

         下面,我举几个例子,大家就能清楚了。

    int main(int argc, char const *argv[])
    {
        char c = 'o';
        int a = (int)c;//相当于把c的acsill码赋值给了a
    
        double d = 3.1231231;
        int b = (int)d; 
    
        //上述两种转换都是C风格
        //下面看看C++风格的类型转换
        
        char c = 'o';
        int a = static_cast<int>c;
    
        double d = 3.1231231;
        int b = static_cast(int)d; 
    
        return 0;
    }

      这种类型转换检查在编译期间完成的。如果强制转换在C中不能通过编译的,在C++中也不能通过编译。

    char* s = “string”;
    int* p = NULL;
    
    p = s;//这里在c语言中编译不能通过
    p = static_cast<int>s;//当然在C++中也不能编译通过

      所以,总结一句话就是:凡是在C语言中能够进行隐式转换的,都能用static_cast进行转换

       在C语言中,如果你想将上面的char* 转换为int* 还真没有什么办法。但是在C++中,提供了下面一个关键字,能够解决问题。

    二、reinterpreter_cast

      reinterpreter_cast,重新解释类型

      现在,我们来看看上面不能进行转化的案例:

    char* s = “string”;
    int* p = NULL;
    
    p = s;
    p = reinterpreter_cast<int>s;
    
    cout<<"p"<<p; //打印出s的地址

      当然,这个还可以這么玩:

    #include<iostream>
    using namespace std;
    
    
    class Tree {};
    
    class Animal{
    public:
        virtual void cry() = 0;
    };
    
    class Dog : public Animal{
    public:
        virtual void cry(){
            cout << "汪汪" << endl;
        }
    
    };
    
    class Cat : public Animal{
    public:
        virtual void cry(){
            cout << "喵喵" << endl;
        }
    };
    
    void main(){
        Dog d1;
        Cat c1;
    
        Animal *pBase = NULL;
    
        pBase = &d1;
    
        pBase = static_cast<Animal *>(&d1); //让C++编译在编译的时候进行 类型检查 
    
        //强制类型转换 
        pBase = reinterpret_cast<Animal *>(&d1); 
        
        {
            Tree t1;
            //pBase = static_cast<Animal *>(&t1); // C++编译器会做类型检查
            pBase = reinterpret_cast<Animal *>(&t1);  //reinterpret_cast 重新解释 ....强制类转换的味道
        }
        system("pause");
    }

      总结之,reinterpreter_cast是一种强制类型转换的语法规则。

      通过 reinterpret_cast<>() 和 static_cast<>()把C语言的强制类型转换 都覆盖了。

    三、dynamic_cast

      dynamic_cast,动态类型转换

      下面,我通过一段代码来看看,这个类型转换有什么用途:

    class Animal{
    public:
        virtual void cry() = 0;
    };
    
    class Dog : public Animal{
    public:
        virtual void cry(){cout << "汪汪" << endl;}
        void doHome(){cout << "看家" << endl;}
    };
    
    class Cat : public Animal{
    public:
        virtual void cry(){cout << "喵喵" << endl;}
        void doThing(){cout << "抓老鼠" << endl;}
    };
    
    
    void playObj(Animal *base){base->cry(); // 1有继承 2虚函数重写 3 父类指针 指向子类对象  发生多态}
    
    void main(){
        Dog d1;
        Cat c1;
    
        Animal *pBase = NULL;
        pBase = &d1;
    
        pBase = static_cast<Animal *>(&d1); //让C++编译在编译的时候进行 类型检查 
        pBase = reinterpret_cast<Animal *>(&d1); //强制类型转换 
    
        playObj(&d1);
        playObj(&c1);
    
        system("pause");
    }

      我们知道,在playObj那里会发生多态,根据传来的不同类的对象,动态的调用属于自己的cry()函数。

      但是,我们现在想要这样需求:当传来的是Dog类对象,调用Dog类的doHome()方法;当传来的是Cat类的对象,调用Cat类的doThing()方法。现在,我们只知道在playObj()函数中会发生多态,动态判断传来的对象。想完成上述功能,就得利用C++提供的dynamic_cast()来动态解析传来的对象。

      下面,我们修改一下playOjb()函数,让其能够完成上述功能。

    void playObj(Animal *base)
    {
        base->cry(); // 1有继承 2虚函数重写 3 父类指针 指向子类对象  ==>多态// dynamic_cast 运行时类型识别  
        Dog *pDog = dynamic_cast<Dog *>(base);//动态地将基类指针转换为不同类的对象
        if (pDog != NULL){
            pDog->doHome(); 
        }
        Cat *pCat = dynamic_cast<Cat *>(base);    //父类对象 ===> 子类对象                   
        if (pCat != NULL){
            pCat->doThing();  
        }
    }

      总结,dynamic_cast()主要完成的是,子类与父类之间类型的转换。

    四、const_cast

      const_cast,常量类型转换

      简言之,取出const变量的只读属性

    void printBuf(const char *  p){
        //p[0] = 'Z'; 不能完成修改
        char *p1 = NULL;//const char * ===> char * //把只读属性 去掉
        p1 = const_cast<char *>(p);
    
        p1[0] = 'Z' ;  //通过p1 去修改了内存空间
        cout << p << endl;
    }
    
    void main(){
        char buf[] = "aaaaaaaaafffffddd";
        char *myp = "aaaaaaaaafffffddd";
    
        //程序员 要确保 p所指向的内存空间 确实能修改 ;如果不能修改会带来灾难性后果
        //printBuf (buf); 数据存放在常量区,不能完成修改
    
        printBuf (myp);
        system("pause");
    }
  • 相关阅读:
    MB52增强
    采购订单创建、修改、审批增强ME21N/ME22N/ME28/ME29N
    SAP调用RestfulApi接口POST数据到外部系统
    SAP ABAP: 把内表数据以excel或csv格式,通过前台或者后台的方式上传至FTP服务器
    Docker 入门
    CentOS 扩容
    ubuntu查看防火墙状态
    No module named ds_store
    Django Ajax 实现历史图形查询
    Django 前端BootCSS 实现分页
  • 原文地址:https://www.cnblogs.com/vipchenwei/p/7542007.html
Copyright © 2011-2022 走看看