美文网首页
C++ 类型转换(23)

C++ 类型转换(23)

作者: maskerII | 来源:发表于2022-06-30 18:41 被阅读0次

    一、前言

    类型转换(cast)是将一种数据类型转换成另一种数据类型。例如,如果将一个整型值赋给一个浮点类型的变量,编译器会暗地里将其转换成浮点类型。

    转换是非常有用的,但是它也会带来一些问题,比如在转换指针时,我们很可能将其转换成一个比它更大的类型,但这可能会破坏其他的数据。

    应该小心类型转换,因为转换也就相当于对编译器说:忘记类型检查,把它看做其他的类型。

    一般情况下,尽量少的去使用类型转换,除非用来解决非常特殊的问题。

    标准c++提供了一个显示的转换的语法,来替代旧的C风格的类型转换。

    使用C风格的强制转换可以把想要的任何东西转换成我们需要的类型。那为什么还需要一个新的C++类型的强制转换呢?

    新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。

    二、静态转换 static_cast

    2.1 基础类型 转换

    // 1. 基础类型 转换
    void test01()
    {
        char a = 'a';
        // char->double
        // static_cast<要转到的类型>(需要将谁转换)
        double d = static_cast<double>(a);
    
        double d1 = (double)a;
    
        cout << d << "   " << d1 << endl;
    }
    

    2.2 有层次关系类的指针或引用 转换

    // 2.有层次关系类的指针或引用 转换
    class Father
    {
    
    };
    
    class Son:public Father
    {
    
    };
    
    class Other
    {
    
    };
    
    // 指针转换
    void test02() {
        Father *f = NULL;
        Son *s = NULL;
    
        // 向上转换 安全
        Father *f1 = static_cast<Father*>(s);
        // 向下转换 不安全
        Son *s1 = static_cast<Son*>(f);
        // 没有继承关系的类之间的指针不能转换 报错
        // Other *other = static_cast<Other *>(f); Err
    
    
    }
    
    // 引用转换
    void test03() {
        Father f;
        Son s;
        Father &ref_f = f;
        Son &ref_s = s;
        // 向上转换 安全
        static_cast<Father &>(ref_s);
        // 向下转换 不安全
        static_cast<Son &>(ref_f);
    }
    

    三、动态转换 dynamic_cast

    dynamic_cast 主要用于类层次间的上行转换和下行转换

    在类层次间上线转换时,dynamic_cast和static_cast的效果是一样的,但在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全

    // 动态转换 dynamic_cast
    void test04() {
       // char a = 'a';
       // dynamic_cast<double>(a);  基础类型不能使用动态转换dynamic_cast
    
       Father *f = NULL;
       Son *s = NULL;
       // 向上转换,安全
       Father *f1 = dynamic_cast<Father *>(s);
       // 向下转换,不安全,会去检查 报错
       // Son *s1 = dynamic_cast<Son *>(f);
    
    }
    
    // 发生多态,向下转换,动态转换不报错
    class Father2
    {
    public:
        virtual void func(){
            
        }
    };
    
    class Son2: public Father2
    {
    public:
        virtual void func(){
            
        }   
    
    };
    
    void test05() {
        Father2 *f = new Son2;
        // 向下转换
        dynamic_cast<Son2 *>(f);
    
    }
    

    四、常量转换const_cast

    常量指针被转化为非常量指针,并且仍然指向原来对象
    常量引用被转化为非常量引用,并且仍然指向原来对象
    注意:不能直接对非指针或非引用的变量进行const_cast操作符去直接移除它的const

    // 常量转换const_cast
    void test06() {
        const int *p = NULL;
        // const -> 不带const
        int *newP = const_cast<int *>(p);
    
        int *pp = NULL;
        const int* newPP = const_cast<const int *>(pp);
    
    
        int a = 10;
        int &ref_a = a;
        const int &ref_a1 = const_cast<const int &>(ref_a);
        cout << ref_a1 << endl;
    
        int b = 20;
        const int &ref_b = b;
        int& ref_b1 =  const_cast<int &>(ref_b);
        cout << ref_b1 << endl;
    
    }
    
    

    五、重新解释转换(reinterpret_cast)

    重新解释转换(reinterpret_cast) 不安全
    主要用于将一种数据类型从一种类型转换为另一种类型
    它可以将一个指针转成一个整数,也可以将一个整数转成一个指针

    // 重新解释转换(reinterpret_cast) 
    class Father
    {
    
    };
    
    class Other
    {
    
    };
    
    void test07() {
        int a = 10;
        int *p = reinterpret_cast<int *>(a);
        cout << p << endl;
    
        Father *f = NULL;
        Other *o = reinterpret_cast<Other *>(f);
    }
    

    https://gitee.com/msmasker/c--study/tree/master/code/day08

    相关文章

      网友评论

          本文标题:C++ 类型转换(23)

          本文链接:https://www.haomeiwen.com/subject/dbocbrtx.html