• C++四种类型转换


    C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:

    TYPE b = (TYPE)a   

    C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。

         static_cast                 静态类型转换。如int转换成char

                      reinterpreter_cast  重新解释类型

                dynamic_cast            命名上理解是动态类型转换。如子类和父类之间的多态类型转换。

           const_cast,             字面上理解就是去const属性。

    4种类型转换的格式:

             TYPE B = static_cast<TYPE> (a) 

    一般性介绍

    1)static_cast<>()   静态类型转换,编译的时c++编译器会做类型检查

    基本类型能转换 但是不能转换指针类型

             2)若不同类型之间,进行强制类型转换,用reinterpret_cast<>() 进行重新解释

             3)一般性结论:

    C语言中  能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;

    C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型 解释。总结:static_cast<>()和reinterpret_cast<>() 基本上把C语言中的 强制类型转换给覆盖

    reinterpret_cast<>()很难保证移植性。

             4)dynamic_cast<>(),动态类型转换,安全的基类和子类之间转换;运行时类型检查

             5)const_cast<>(),去除变量的只读属性

    典型案例

    static_cast和reinterpreter_cast
    #include <iostream>
    using  namespace std;
    
    int main()
    {
        double dpi = 3.1415926;
    
        int num1 = (int)dpi;  // c类型转换
        int num2 = static_cast<int> (dpi); // c++静态类型转换, 编译时编译器会进行类型检查
        int num3 = dpi;      // c语言中,隐士类型转换的地方,去可以使用,有警告,但是加上Static_cast就没了
    
        // char* ===> int*
        char *p1 = "hello world";
        int  *p2 = NULL;
    
        // p2 = static_cast<int*>(p1);  // 编译器会进行类型检查,有错就提示出来
    
        p2 = reinterpret_cast<int*> (p1);
    
        cout << "p1 = " << p1 <<endl;  //%s 一个字符串,如果是*p1就是h
        cout << "p2 = " << p2 << endl; //%d 字符串的首地址
    
        // 总结:通过reinterpreter_cast<>(),static_cast<>(),把c语言中的强制类型都覆盖了
        return 0;
    
    }

    //结果
    //p1 = hello world
    //p2 = 0x47f048

     

    dynamic_cast用法和reinterpret_cast用法

    #include <iostream>
    using  namespace std;
    
    /*
        C分格的强制类型转换(Type cast),很简单,不管什么类型,都是
        Type b = (Type)a;
    
        C++风格提供了4种类型转换操作符,来对应不同的场合的应用
            static_cast    静态类型转换,如int转换成char
            reinterpreter_cast  重新解释类型
            dynamic_cast       命名上理解动态类型转换,如子类和父类之间的多态类型转换
            const_cast     字面理解就是const属性
    
            4中类型转换格式:
            Type b = static_cast<Type> (a);
    */
    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父类指针(引用) 指向子类对象 ===> 发生多态
        cout << endl;
    
        // 需求:识别子类对象
        // dynamic_cast 运行时类型识别
    
        Dog *pDog = dynamic_cast<Dog *> (&base);
        if (pDog != NULL)
        {
            pDog->doHome();  // 做自己特有的工作
        }
    
        cout << endl;
    
        Cat *c1 = dynamic_cast<Cat *> (&base);  // 父类对象 ==> 子类对象
                                               // 向下转型
                                              // 把老子转成小子
        if (c1 != NULL)
        {
            c1->doThing();
        }
    
    }
    class Tree{};
    int main()
    {
        Dog d1;
        Cat c1;
    
        Animal *pBase = NULL;
        pBase = &d1;
        pBase = static_cast<Animal*>(&d1); // c++编译时,进行类型检查,将d1指针转换成父类指针
    
        // 强制类型转换
        pBase = reinterpret_cast<Animal*>(&d1);
    
        {
            Tree t1;
            // 将树指针 转换成动物类指针
    //        pBase = static_cast<Animal*>      (&t1);  // c++编译器,类型检查 不通过
            pBase = reinterpret_cast<Animal*> (&t1); // 可以 重新解释。。。。强制类型转换的味道
    
        }
        playObj(d1);
        playObj(c1);
        return 0;
    }

    //结果
    // 汪汪
    //
    // 看家
    //
    // 喵喵
    //
    //
    // 抓老鼠

     

     const_cast用法

    // const char*p,中得const表示 p指向的内存空间 不可以修改 就是*p(值)不能改
    void printBuf(const char*p)
    {
    //     p[0] = 't';  报错
    
        char *p1 = NULL;
    
        // 程序员要清楚地知道:变量转换前,和转换后的类型
        p1 = const_cast<char*>(p);   // 将p 由const char* == > char*
        cout << "p = " << p << endl;
    
        p1[1] = 't';  // 通过p1修改了 p指向的内存空间
    
        // 转换后 可以间接修改p的值,不准换的话,也不能间接修改
        cout << "p = " << p << endl;
    
    }
    
    int main()
    {
         char buf[] = "aaaaa";
        // 程序员 要确保 p所指向的内存空间,确实能修改,如果不能修改,会带来灾难性的后果
         printBuf(buf);
    
    //    char *myBuf = "bbbbbbbb";  // 常量,不能修改
    //    printBuf(myBuf);
        return 0;
    }
     
  • 相关阅读:
    201521123063 《Java程序设计》 第8周学习总结
    201521123063 《Java程序设计》 第7周学习总结
    201521123064 《Java程序设计》第11周学习总结
    201521123064 《Java程序设计》第10周学习总结
    201521123064 《Java程序设计》第9周学习总结
    201521123064 《Java程序设计》第8周学习总结
    201521123064 《Java程序设计》第7周学习总结
    201521123064 《Java程序设计》第6周学习总结
    201521123064 《Java程序设计》第5周学习总结
    201521123064 《Java程序设计》第4周学习总结
  • 原文地址:https://www.cnblogs.com/xiaokang01/p/12376683.html
Copyright © 2020-2023  润新知