• C++中的类型转换 static_cast、dynamic_cast、const_cast、reinterpret_cast


    类型转换可以让我们将一种类型的变量当做另外一种类型来使用,常见的类型转换方式包括

    C风格的类型转换

    转换格式为:(类型)变量

    int a = 10;
    double b = a;
    float c = b;
    Base* base = (Base*)new Derived();

    C++自带的类型转换

    • static_cast
    • dynamic_cast
    • const_cast
    • reinterpret_cast

    为什么有了C风格的类型转换方式后C++还添加这四种类型转换方式呢?

    因为C风格的类型转换可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向非const对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的指针,这两种转换之间的差别是巨大的,但是传统的c语言风格的类型转换没有区分这些。还有一个缺点就是,c风格的转换不容易查找,他由一个括号加上一个标识符组成,而这样的东西在c++程序里一大堆。

    static_cast

    类似与C风格的无条件静态类型转换

    1、基类和子类之间的转换,其中:子类->基类是安全的,但是基类->子类是不安全的,建议使用dynamic_cast进行运行时判断进行基类转子类。

    2、基本数据类型之间的转换,int, char, float,注意不可以进行无关类型指针的转换。

    3、转换空指针为任何类型的空指针

    Base* base1 = static_cast<Base*>(new Derived());	
    Derived* base2 = static_cast<Derived*>(new Base());	 //基类->子类,有风险,不推荐使用
    
    double num = static_cast<double>('a');	//char->double
    // double* ptr = static_cast<double*>(new int(10));	错误,无关类型的指针转换,转换无效
    	
    double* ptr = static_cast<double*>(nullptr);	//空指针->任意类型的空指针
    

    dynamic_cast

    动态转换主要是用于类的层次间、基类子类间转换,具有检验功能,在无法进行转换时返回nullptr。如果转换的是引用,失败时会抛出std::base_cast异常。可以通过返回值进行判断是否成功转换。

    Base* base = dynamic_cast<Base*>(new Derived());		//成功
    if (base == nullptr) {
    	std::cout << "derived -> base 失败" << std::endl;
    }
    
    Derived* derived = dynamic_cast<Derived*>(new Base());	 //失败
    if (derived == nullptr) {
    	std::cout << "base -> derived 失败" << std::endl;
    }

    返回失败

    const_cast

    用于移除、添加变量的const属性,注意C++中其他的三类转换都没有移除const属性的能力,对于const_cast主要用来对顶层、底层的const进行转换。为什么不可以对变量的const进行修改呢?因为没有意义。

    int i = 10;
    const int* p = &i;
    const int* ci = const_cast<const int*>(p);
    //*ci = 20; 提示错误,表达式必须是可修改的左值
    int* c = const_cast<int*>(p);
    *c = 20;
    

    reinterpret_cast

    re重新的意思,interpret解读、翻译的意思,顾名思义将数据重新按照另外一种类型进行解读,一般很少用到,不清楚自己在操作什么数据时,请谨慎使用。比如将四个字符当做当做一个浮点数进行处理。

    char ch[4] = { 'a', 'b', 'c', 'd' };
    float* f = reinterpret_cast<float*>(ch);	//四个字符共四个字节正好当做一个浮点数来处理(不严谨,具体根据各个平台浮点数字节大小可能不一样)
    
    std::cout << *f << std::endl;
    

    输出

     本质上C++中的四种类型转换都是语法糖,所有能做的C风格转换也可以做到。但是使用C++中的类型转换,可以让我们更好的追踪到我们的项目里面的哪里有用到类型转换,这是C风格转换所不具有的优势的。

    更多参考:

    https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used

  • 相关阅读:
    创建型设计模式之-单例
    设计模式(1、创造型2、结构型、3行为型)
    手写IOC容器和两种注入(构造方法注入和属性注入)
    从依赖倒置原则到IOC控制反转
    自定义HttpHandler可以做什么
    一个用户在浏览器上输入网址怎么走到我们写的.net程序中的,请求到管道处理
    代理Nginx
    .Net Expression表达式目录树(自己动态创建表达式目录树)
    canvas绘制圆环进度条
    城市二级联动
  • 原文地址:https://www.cnblogs.com/yangxunwu1992/p/14008108.html
Copyright © 2020-2023  润新知