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

    C++强制类型转换

    C++中有四种强制类型转换操作符:static_cast,dynamic_cast,const_cast,reinterpret_cast,下面分别介绍。

    1.static_cast

    只完成编译时期的转换检查,主要有几个应用场合,安全性由程序员自己保证。

    1. 用于基类和子类之间指针或引用的转换
    2. 任何类型指针与void指针转换
    3. 空指针转换成目标指针
    4. 基本数据类型的转换,安全性由程序员保证,不做检查,一般将小转大(例如intdouble)能够保证不丢失数据

    2.dynamic_cast

    将一个基类对象指针(或引用)转换成派生类指针(或引用),dynamic_cast会根据基类指针是否真正指向派生类对象来做相应处理。

    dynamic_cast<typename>(expression)

    该运算符将expression转换成typename类型。注意:typename必须是类的指针、类的引用或者void*,并且expressiontypename类型保持一致,同为指针、引用或void*

    dynamic_cast运算符可以在执行期决定真正的类型。如果 downcast 是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果 downcast 不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。转换引用时失败,会抛出std::bad_cast异常,需要catch该异常,做相应处理
    dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
    在类层次间进行上行转换时,dynamic_caststatic_cast的效果是一样的;
    在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

    #include"stdlib.h" 
    #include<tchar.h> //工程文件中可直接使用,无需定义
    #include<iostream>
    using namespace std;
     
    class Base
    {
    public:
        virtual void f() {cout << "Base::f" << endl;}
        void f1() {cout << "Base::f1" << endl;}
    private:
        double x;
        double y;
    };
     
    class Derived : public Base
    {
    public:
        virtual void f() {cout << "Derived::f" << endl;}
        virtual void k() {cout << "Derived::k" << endl;}
    private:
        double z;
    };
     
    class Base1
    {
    public:
        virtual void g() {cout << "Base1::g" << endl;}
        void g1() {cout << "Base1::g1" << endl;}
    };
     
    class Derived1 : public Base, public Base1
    {
    public:
        virtual void f() {cout << "Derived1::f" << endl;}
        virtual void h() {cout << "Derived1::h" << endl;}
    };
     
    void Test1()
    {
        //对于单继承,
        //如果pD真的指向Derived,用dynamic_cast和static_cast效果相同
        Base* pD = new Derived;
         
        Derived* pD1 = dynamic_cast<Derived*>(pD);
        pD1->f();
        pD1->k();
        pD1->f1();
         
        Derived* pD2 = static_cast<Derived*>(pD);
        pD2->f();
        pD2->k();
        pD2->f1();
         
        //但是如果pB不是真的指向Derived,则用dynamic_cast则返回NULL,能够更早的禁止error的发生,
        //如果用static_cast虽然返回的不为NULL,但是运行时可能抛出exception。
        /**/////Errorcode
        //Base* pB = new Base();
        //Derived* pD3 = static_cast<Derived*>(pB);
        //pD3->f();
        //pD3->k();
        //pD3->f1();
        //Derived*pD4 = dynamic_cast<Derived*>(pB);
        //pD4->f();
        //pD4->k();
        //pD4->f1();
    }
     
    void Test2()
    {
        //对于多重继承,
        //如果pD真的指向的是Derived1,使用dynamic_cast和static_cast都可以转化为Derived1,
        //但是如果要转化为Base的兄弟类Base1,必须使用dynamic_cast,使用static_cast不能编译。
        Base* pD = new Derived1;
        Derived1* pD1 = dynamic_cast<Derived1*>(pD);
        pD1->f();
        pD1->h();
        pD1->f1();
         
        Derived1* pD2 = static_cast<Derived1*>(pD);
        pD2->f();
        pD2->h();
        pD2->f1();
         
        Base1* pB1 = dynamic_cast<Base1*>(pD);
        pB1->g();
         
        /**/////errorcannotcompiler
        //Base1* pB2 = static_cast<Base1*>(pD);
        //pB2->g();
        //当然对于pB不是真的指向Derived1,想要转化为Derived1或Base的兄弟类Base1,情况与Test1中的error情况相同。
    }
     
    int _tmain(int argc, _TCHAR*argv[])
    {
        Test1();
        Test2();
        return 0 ;
    }
    

    3.const_cast

    const_cast主要作用是:修改类型的constvolatile属性。使用该运算方法可以返回一个指向非常量的指针(或引用)指向b1,就可以通过该指针(或引用)对它的数据成员任意改变。

    int const & i = 100;
    int & m = const_cast<int&>(i);
    m=200;
    cout<<i<<endl;
    
    //输出结果:
    //200
    

    4.reinterpret_cast

    所有指针的值都是一个表示地址的数值,值本身的转换是没有任何问题的。“再解释”是指对指针指像的哪段内存重新解释。

    可以实现不同类型指针之间的相互转换,同时也支持将指针与数字之间的转换

    float f = 0;
    float* pf = &f;
    int* pi = reinterpret_cast<float*>(pf);
    
    //pi重新“解释”了pf,
    

    以上内容引自:https://zouzhongliang.com/index.php/2019/03/12/c类型转换/

  • 相关阅读:
    HTML元素解释
    Java命名规范
    HDU 1058 Humble Numbers(DP,数)
    HDU 2845 Beans(DP,最大不连续和)
    HDU 2830 Matrix Swapping II (DP,最大全1矩阵)
    HDU 2870 Largest Submatrix(DP)
    HDU 1421 搬寝室(DP)
    HDU 2844 Coins (组合背包)
    HDU 2577 How to Type(模拟)
    HDU 2159 FATE(二维完全背包)
  • 原文地址:https://www.cnblogs.com/bear-Zhao/p/14709838.html
Copyright © 2011-2022 走看看