zoukankan      html  css  js  c++  java
  • C++四种cast强制类型转换

    转载自https://blog.csdn.net/wlx990074575/article/details/108005854

    c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比如

    1、你可以把一个指向const对象的指针转换成指向非const对象的指针

    2、把一个指向基类对象的指针转换成指向一个派生类对象的指针

    这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。

    还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,(TYPE)EXPRESSION   而这样的东西在c++程序里一大堆。

    所以c++为了克服这些缺点,引进了4新的类型转换操作符,他们是static_cast 、const_cast 、dynamic_cast 、reinterpret_cast

    一、const_cast

    int n = 5;
    int *k1 = const_cast<int*>(&n);  //指针
    *k1 = 1;
    int &k2 = const_cast<int&>(n);   //引用
    k2 = 2;

    const_cast去除const(volatile)属性,将只读变为可读写;

    const int a = 10;
        int* b = const_cast<int*>(&a);
        *b = 11;//指针b的属性变成可读可写

    const_cast只针对指针、引用和this指针,其他情况的话就会出错,如下代码所示;

    int n = 5;
    int k1 = const_cast<int>(n);  //编译出错
    k1 = 1;                       //编译出错

    二、static_cast

    static_cast第一个作用是代替隐式转换 ,比如:

    1、void* 转换为任意类型的指针

    2、任意类型的指针转换为void*

    3、编译器允许的跨类型转换,比如char类型转换为int类型,double转int型   

       int n = 10;
        char c = 'a';
        void *p = nullptr;
        int *k = static_cast<int*>(p);
        n = static_cast<int>(c); //n就变成了97,ASCLL码中字符a的位置,    相当于int n = (int)c;

    static_cast第二个作用是做基类与派生类的转换,派生类转换成基类是安全的,基类转换成派生类是不安全的,因为往往子类的内容比父类多,

    static_cast可以将子类转换成父类,但是不提供安全性检查

    class A{
    public:
        void m() {};
    
    };
    class B:public A//普通继承 
    {
    
    };
    int main() {
        A* aa;
        B* bb=static_cast<B*> (aa);//基类指针向下转换为派生类指针,不进行类型检查,不安全
        system("pause");
        return 0;
    }

    三、dynamic_cast

    dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,弥补了static_cast类型不安全的缺陷,比static_cast更安全

    用于有虚函数的基类与其派生类之间的转换,特点是进行运行时检测转换类型是否安全,如果转换失败返回nullptr,依赖于RTTI技术,但是有额外的函数开销,所以非必要的时候不使用。

    class A{
    public:
        virtual void m() {};// C现在是 多态
    
    };
    class B:public A 
    {
    
    };
    int main() {
        A* aa;
        B* bb=dynamic_cast<B*> (aa);//基类指针向下转换为派生类指针
        system("pause");
        return 0;
    }

    RTTI是一种意思是运行时类型信息,它提供了运行时确定对象类型的方法,换句话说,RTTI是一种可以获取变量在运行时的实际指向的机制,使用了typeid()函数

     详细参考 https://www.cnblogs.com/xuelisheng/p/9479288.html

    四、reinterpret_cast

    reinterpret代替显示转换,用于转换各种高风险的转换(隐式转换无法转换的)

    它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)

    但是不进行检查,只是进行强制的复制,有安全隐患,一般不用

    reinterpret_cast是四种强制转换中功能最为强大的,它可以暴力完成两个完全无关类型的指针之间或指针和数之间的互转,比如用char类型指针指向double值。它对原始对象的位模式提供较低层次上的重新解释(即reinterpret),完全复制二进制比特位到目标对象,转换后的值与原始对象无关但比特位一致,前后无精度损失。
    int main() {
        double d = 12.1;
        char* p = reinterpret_cast<char*>(&d); // 将d以二进制(位模式)方式解释为char,并赋给*p
        double* q = reinterpret_cast<double*>(p);
        cout << *q << endl; // 12.1
        system("pause");
        return 0;
    }



  • 相关阅读:
    Mongdb 简单增删改查
    mongdb的安装
    VO,DO,DTO,PO,POJO,EJB
    JavaScript是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式!
    判断DataTale中判断某个字段中包含某个数据
    查询表中某个字段的值出现次数大于1的数据
    判断对象数组中是否含有某个对象。
    C# datatable 重新排序
    jquery 验证大于0的整数
    jQuery 心跳请求
  • 原文地址:https://www.cnblogs.com/-citywall123/p/13514067.html
Copyright © 2011-2022 走看看