美文网首页
static_cast,dynamic_cast,const_c

static_cast,dynamic_cast,const_c

作者: 钟离惜 | 来源:发表于2020-08-20 14:29 被阅读0次

    C语言强制类型转换

    (type-id)expression//转换格式1

    char a;
    int n = (int)a;
    

    type-id(expression)//转换格式2

    char a;
    int n = int(a);
    

    static_cast

    static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换,例如non-const对象转为const对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
    1、用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
    进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
    进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
    2、用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
    3、将void*转换成目标类型指针。
    4、把任何类型的表达式转换成void类型。
    注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。

    char a = 'a';
    int b = static_cast<char>(a);//正确,将char型数据转换成int型数据
    
    double *c = new double;
    void *d = static_cast<void*>(c);//正确,将double指针转换成void指针
    
    int e = 10;
    const int f = static_cast<const int>(e);//正确,将int型数据转换成const int型数据
    
    const int g = 20;
    int *h = static_cast<int*>(&g);//编译错误,static_cast不能转换掉g的const属性
    
    if(Derived *dp = static_cast<Derived *>(bp)){//下行转换是不安全的
      //使用dp指向的Derived对象  
    }
    else{
      //使用bp指向的Base对象  
    }
    
    if(Base*bp = static_cast<Derived *>(dp)){//上行转换是安全的
      //使用bp指向的Derived对象  
    }
    else{
      //使用dp指向的Base对象  
    }
    

    dynamic_cast

    dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换(cross cast)。
    在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
    在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。dynamic_cast是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。
    1、指针类型
    举例,Base为包含至少一个虚函数的基类,Derived是Base的共有派生类,如果有一个指向Base的指针bp,我们可以在运行时将它转换成指向Derived的指针,代码如下:

    if(Derived *dp = dynamic_cast<Derived *>(bp)){
      //使用dp指向的Derived对象  
    }
    else{
      //使用bp指向的Base对象  
    }
    

    2、引用类型
    因为不存在所谓空引用,所以引用类型的dynamic_cast转换与指针类型不同,在引用转换失败时,会抛出std::bad_cast异常,该异常定义在头文件typeinfo中。

    void f(const Base &b){
     try{
       const Derived &d = dynamic_cast<const Base &>(b);  
       //使用b引用的Derived对象
     }
     catch(std::bad_cast){
       //处理类型转换失败的情况
     }
    }
    

    const_cast

    const_cast,用于修改类型的const或volatile属性。
    该运算符用来修改类型的const(唯一有此能力的C++style转型操作符)或volatile属性。除了const 或volatile修饰之外, new_type和expression的类型是一样的。
    ①常量指针被转化成非常量的指针,并且仍然指向原来的对象;
    ②常量引用被转换成非常量的引用,并且仍然指向原来的对象;
    ③const_cast一般用于修改底指针。如const char *p形式。

    const int g = 20;
    int *h = const_cast<int*>(&g);//去掉const常量const属性
    
    const int g = 20;
    int &h = const_cast<int &>(g);//去掉const引用const属性
    
     const char *g = "hello";
    char *h = const_cast<char *>(g);//去掉const指针const属性
    

    reinterpret_cast

    new_type必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。
    reinterpret_cast意图执行低级转型,实际动作(及结果)可能取决于编辑器,这也就表示它不可移植。
    static_cast和reinterpret_cast的区别主要在于多重继承,比如:

    class A {
        public:
        int m_a;
    };
     
    class B {
        public:
        int m_b;
    };
     
    class C : public A, public B {};
    
    C c;
    printf("%p, %p, %p", &c, reinterpret_cast<B*>(&c), static_cast <B*>(&c));
    

    前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节,这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c里面有m_a,m_b,转换为B*指针后指到m_b处),而reinterpret_cast却不会做这一层转换。

    转载文章
    C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast

    相关文章

      网友评论

          本文标题:static_cast,dynamic_cast,const_c

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