• C++中的类型转换


    C++中的类型转换:static_cast、reinterpret_cast、const_cast、dynamic_xast

    一般情况下我们写的类型转换,就是加上一个圆括号 float a;int b =(int)a;
    但是这样有缺陷:因为所有的形式都是一样的。所以可视性就会很差,如果发生错误,不容易找到错误的原因。所以c++引入了强制类型转换操作符。上面的四种。

    Static_cast

    它用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可以用static_cast,(也就是类型相近的,隐式类型转换),但是它不能用于两个不相关的类型进行转换。
    怎么说呢,相近类型,像int 和double float 就是。用于这些普通类型之间的转换
    用法:int a = 2;float d = static_cast(a);
    一句话总结:这个static_cast就是用来进行类型相近的类型转换的。

    Reinterpret_cast

    它通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。怎么说呢,就是说将一种类型转换为另外一种,那肯定是有风险的了。
    举例说明:

    typedef int (*FUN)();
    int Add(int i,int j)
    {
        return i + j;
    }
    void test()
    {
        FUN f = reinterpret_cast<FUN>(Add);
        int b = f();  这里就是讲一个函数指针转换为了一个整型的数,很可怕吧
        cout << b <<endl;
    }

    总结:也就是说这个reinterpret_cast可以让编译器以FUN的定义方式来看待Add函数。所以说呢很BUG,这个转换指针的代码时不可以移植的,所以呢,是不建议这样是用的。
    函数指针并不能保证所有的函数指针都可一这样使用,所以这样用会产生不确定的后果。尽量不要这样用。

    一句换总结;reinterpret_cast是用来进行不同类型之间的转换,风险较大,不建议使用

    Const_cast

    他的用途就是用来删除变量的const属性,方便赋值。

    Const int a = 2; int *p = const_cast<int*>(&a); *p = 3;

    但是呢,你看呢,本来定义的使const就是不想让他改变,结果你还给我改变了。这样也不太好,所以呢,在用的时候注意,在程序中这个变量的具体意义。

    Dynamic_cast

    用于将一个父类对象的指针转化为子类对象的指针或者引用。(动态转换,和static_cast相反)
    1.向上转型:子类对象指针->父类指针或者引用(不需要转换)
    2.向下转型:父类对象指针->子类指针或者引用(用dynamic_cast转型是安全的)
    3.Dynamic_cast只能用于含有虚函数的类。
    4.Dynamic_cast会先检查是否能转换成功,能就转换,不能就返回0

    class AA
    {
    public:
        virtual void f()
        {}
    };
    class BB:public AA
    {};
    void fun(AA*pa)
    {
        BB*pb1 = static_cast<BB*>(pa);  强转
        BB*pb2 = dynamic_cast<BB*>(pa);  将父类强制转换为子类,会检查是否能转
    cout<<"pb1:"<<pb1<<endl;
        cout<<"pb2:"<<pb2<<endl;
    
    }
        AA a;
        BB b;
        fun(&a);
        fun(&b);

    注意:强制类型转换,不管怎么说,它都是强制的,所以说终归是不安全的,所以我们在使用之前都先考虑清楚,是不是必须要用,还有没有其他方法可以代替,如果不需要用,注意要加上强制转换值的作用域,以减少发生错误的机会。尽量避免用强制类型转换

    例题
    Const int i=0; int j = (int)&i; *j =1;
    printf(“%d,%d”,i,j);

    输出结果:在C语言中,输出1,1 在c++中输出 0,1;
    这是c++中的优化机制,因为 i 是const类型的,编译器就认为我们是不想改变它的,所以就把它放在了寄存器里面,在用的是后就直接从寄存器里面拿出来,这样更加快速,但是呢,在这里我们用指针把它给改变了,看起来输出的时候两个都应该是1 指向同一块空格键了嘛。但是由于c++中编译器的优化,输出的时候直接去寄存器里面找i 所以,结果就还是原来存进去的那个0。(这个题很坑遇到两次了,这次总结类型转换,想起来了,写出来加强一下记忆)。

  • 相关阅读:
    Linux安装Docker
    Api接口防攻击防刷注解实现
    Api接口鉴权注解实现
    RSA加解密 Java
    Windows安装Mysql 5.7
    Mysql创建自增序列
    new String与toString的区别
    各排序算法复杂度及稳定性
    描述快排以及其复杂度
    innodb和myisam的区别
  • 原文地址:https://www.cnblogs.com/chan0311/p/9427323.html
Copyright © 2020-2023  润新知