• C++强制类型转换


    本文介绍C++的四种强制类型转换,转载请注明出处。

    一、const_cast:

      去除指针或引用的const属性。

    1、转化常量指针为非常量的指针,并且仍然指向原来的对象; 

    2、转化常量引用为非常量的引用,并且仍然指向原来的对象; 

    3、const_cast一般用于修改指针。如const int *ptr形式。

    用法:

    #include <iostream>
    using namespace std;
    
    void main(){
        cout << "const_cast测试" << endl;
        int ary[4] = { 1, 2, 3, 4 };
        const int *c_ary = ary;
        //c_ary[0] = 5;//错误,常量不能改变
        int *ary2 = const_cast<int*>(c_ary);//const_cast将常量指针转化为非常量指针
        ary2[0] = 5;//正确
    
        int a = 2;
        const int &c_a = a;
        //c_a = 5;//错误,常量不能改变
        int &a2 = const_cast<int&>(c_a);//const_cast将常量引用转化为非常量引用
        a2 = 5;//正确
    
        const int c_val = 3;
        int &ref_val = const_cast<int&>(c_val);//得到去const的引用
        int *ptr_val = const_cast<int*>(&c_val);//得到去const的指针
        
        system("pause");
    }

    二、static_cast

      转换数据类型,类的上下行转换。

    1、转换数据类型,由于没有运行时类型检查来保证转换的安全性,不安全;

    2、类的上下行转换,由于没有运行时类型检查,下行转换不安全;

    3、static_cast不能转换掉原有类型的const、volatile、或者 __unaligned属性;

    c++ 的任何的隐式转换都是使用 static_cast 来实现。

    #include <iostream>
    using namespace std;
    
    void main(){
        cout << "static_cast测试" << endl;
        float f_pi = 3.1415;
        int i_pi = static_cast<int>(f_pi);
    
        //类的上下行转换
        class Base{
        };
        class Derived :public Base{
        };
    
        //上行转换 Derived->Base,安全
        Derived derived;
        Base *base_ptr = static_cast<Base*>(&derived);
    
        //下行转换 Base->Derived,由于没有动态类型检查,编译能通过但不安全
        Base base;
        Derived *derived_ptr = static_cast<Derived*>(&base);
        
        system("pause");
    }

     三、dynamic_cast

      安全的上下行转换。

      上行转换(子类到基类的指针转换),dynamic_cast成功转换,运行正常且输出预期结果。而下行转换(基类到子类的转换),dynamic_cast在转换时也没有报错,但是输出给base2deri是空指针,说明dynami_cast在程序运行时对类型转换对“运行期类型信息”(Runtime type information,RTTI)进行了检查,是安全的(转换后为空指针,不会指向未知内存,保证了使用安全)。而用static_cast由于没有动态类型检查,编译能通过但不安全。

    #include <iostream>
    using namespace std;
    
    class Base{
    public:
        Base() {}
        ~Base() {}
        void print() {
            std::cout << "This is Base" << endl;
        }
    
        virtual void virtual_foo() {}
    };
    
    class Derived : public Base{
    public:
        Derived() {}
        ~Derived() {}
        void print() {
            std::cout << "This is Derived" << endl;
        }
    
        virtual void virtual_foo() {}
    };
    
    void main(){
        cout << "dynamic_cast测试" << endl;
        //上行转换 Derived->Base
        Derived *derived = new Derived();
        derived->print();//输出This is Derived
        Base* deri2base = dynamic_cast<Base*>(derived);
        if (deri2base != nullptr){
            derived->print();//输出This is Derived
        }
    
        //下行转换 Base->Derived
        Base *base = new Base();
        base->print();//输出This is Base
        Derived* base2deri = dynamic_cast<Derived*>(base);
        if (base2deri != nullptr){//base2deri为空,不进行打印
            base2deri->print();
        }
        
        Base *base2 = new Derived();
        base2->print();//输出This is Base
        //Derived* deri2 = new Base();//错误。不能直接将Base*转换为Derived*,即不能直接下行转换。
    
        delete derived;
        derived = nullptr;
        delete base;
        base = nullptr;
    
        system("pause");
    }

    输出:

    四、reinterpret_cast

      进行无关类型的转换

      用在任意的指针间的转换,任意引用间的转换,指针和足够大的整型之间的转换,整型到指针的转换。

    #include <iostream>
    using namespace std;
    
    void main(){
        int *p = new int(5);
        cout << "p的地址: " << hex << p << endl;//std::hex用于以16进制输出十进制数
        int p_addr = reinterpret_cast<int>(p);
        cout << "p_addr的值: " << hex << p_addr << endl;
        
        delete p;
        p = nullptr;
    
        system("pause");
    }

    输出:

    可见已经将指针p转换为了int型,指针p的地址的值和整形p_addr的数值相同,都为0x44b4b8。

  • 相关阅读:
    关于table表格的一些问题
    leetcode 845. 数组中的最长山脉 做题笔记
    leetcode 845. 数组中的最长山脉 做题小结
    leetcode 925. 长按键入小结
    leetcode 925. 长按键入小结
    java单链表反转 详细讲述
    java单链表反转 详细讲述
    Leetcode 3. 无重复字符的最长子串 做题小结
    Leetcode 3. 无重复字符的最长子串 做题小结
    复变函数的幂函数
  • 原文地址:https://www.cnblogs.com/zeppelin5/p/10075569.html
Copyright © 2020-2023  润新知