zoukankan      html  css  js  c++  java
  • 【C++】C++之类型转换

    作者:李春港
    出处:https://www.cnblogs.com/lcgbk/p/14209848.html

    一、前言

    在C语言中,我们经常会对数据进行类型转换,但都是强制性的类型装换,自然就会引发访问不安全的问题,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,而且这种转换方式不利于我们审查代码,且程序运行时也可能会出bug,所以C++为了提高类型装换的安全性,关于类型转换引入了四种方式:static_cast、const_cast、dynamic_cast、reinterpret_cast,接下来看下其四种类型装换的应用场景。

    二、static_cast

    2.1 使用场景

    基本数据类型之间的转换使用,例如float转int,int转char等,在有类型指针和void*之间转换使用,子类对象指针转换成父类对象指针也可以使用static_cast。

    非多态类型转换一般都使用static_cast,而且最好把所有的隐式类型转换都是用static_cast进行显示替换,不能使用static_cast在有类型指针之间进行类型转换。

    2.2 实例

    #include <iostream>
    
    using namespace std;
    
    struct Base {
        virtual void Func() { cout << "Base Func 
    "; }
    };
    
    struct Derive : public Base {
        void Func() override { cout << "Derive Func 
    "; }
    };
    
    int main() 
    {
        float f = 1.23;
        cout << "f " << f << endl;
        int i = static_cast<int>(f);
        cout << "i " << i << endl;
    
        void *p;
        int *i_p = static_cast<int *>(p);
        void *pi = static_cast<void *>(&f);
        int *pi = static_cast<int *>(&f);  // error invalid static_cast from type ‘float*’ to type ‘int*’
    
        Derive d;
        d.Func();
        Base *b = static_cast<Base *>(&d); 
        b->Func();
        return 0;
    }
    

    三、dynamic_cast

    3.1 使用场景

    用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行),因为dynamic_cast是运行时检查,检查需要运行时信息RTTI.如果不清楚什么是RTTI,可以去了解下C++的RTTI机制。

    3.2 实例

    #include <iostream>
    
    using namespace std;
    
    struct Base {
        virtual void Func() { cout << "Base Func 
    "; }
    };
    
    struct Derive : public Base {
        void Func() override { cout << "Derive Func 
    "; }
    };
    
    int main() {
        Derive d;
        d.Func();
        Base *b = dynamic_cast<Base *>(&d);
        b->Func();
        Derive *dd = dynamic_cast<Derive *>(b);
        dd->Func();
        return 0;
    }
    

    四、const_cast

    4.1 使用场景

    用于常量指针或引用与非常量指针或引用之间的转换,只有const_cast才可以对常量进行操作,一般都是用它来去除常量性,去除常量性是危险操作,还是要谨慎操作。

    4.2 实例

    int main() {
        int data = 10;
        const int *cpi = &data;
    
        int *pi = const_cast<int *>(cpi);
    
        const int *cpii = const_cast<const int *>(pi);
        return 0;
    }
    

    五、reinterpret_cast

    5.1 使用场景

    没啥场景,类似C语言中的强制类型转换,什么都可以转,万不得已不要使用,一般前三种转换方式不能解决问题了使用这种强制类型转换方式。

    5.2 实例

    int main() {
        int data = 10;
        int *pi = &data;
    
        float *fpi = reinterpret_cast<float *>(pi);
    
        return 0;
    }
    

    六、总结

    方式 使用场景
    static_cast 基本数据类型之间的转换使用,例如float转int,int转char等;子类对象指针转换成父类对象指针也可以使用static_cast;在有类型指针和void*之间转换使用,不能使用static_cast在有类型指针之间进行类型转换。
    dynamic_cast 用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行)
    const_cast 用于常量指针或引用与非常量指针或引用之间的转换。
    reinterpret_cast 类似C语言中的强制类型转换,什么都可以转,尽量不要使用此方式。
  • 相关阅读:
    [HDU 2089]不要62
    [WC 2011]Xor
    [BJOI 2011]元素
    [NOIp 2014]解方程
    [UVa 1326]Jurassic Remains
    [BZOJ 2152]聪聪可可
    [IOI 2011]Race
    [测试题]打地鼠
    [POJ 2828]Buy Tickets
    [测试题]gene
  • 原文地址:https://www.cnblogs.com/lcgbk/p/14209848.html
Copyright © 2011-2022 走看看