zoukankan      html  css  js  c++  java
  • [C++] 类型转换

    类型转换

    在C++语言中,某些类型之间有关联,如果两种类型有关联,那么当程序需要其中一种类型的运算对象时,可以用另一种关联类型的对象或值来替代。换句话说,如果两种类型可以相互转换,那么它们就是关联的。

    例如

    int ival = 3.14 + 3;
    // 3.14 + 3 = 6 : double + int ~ double
    // ival = 6 : double ~ int

    何时发生隐式转换

    1、在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型

    2、在条件中,非布尔值转换成布尔类型

    3、初始化过程中,初始值转换成变量的类型;在赋值语句中,右侧运算对象转换成左侧运算对象的类型。

    4、如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型。

    5、函数调用时也会发生类型转换

    算术转换

    算术转换的含义是把一种算术类型转换成另外一种算术类型,

    其中:运算符的运算对象将转换成最宽的类型;当表达式中既有浮点类型也有整数类型时,整数值将转换成相应的浮点类型

    整型提升

    整型提升负责把小整数类型转换成较大的整数类型。要求转换后的类型要能容纳原类型所有可能的值

    无符号类型的运算类型

    如果某个运算对象的类型是无符号类型,那么转换的结果就要依赖于机器中各个整数类型的相对大小

    首先要进行整型提升,如果带符号的类型不大于无符号的类型,然后对于有符号的数转换成无符号的数。如果带符号的类型大于无符号的类型,那么转换的结果依赖于机器。

    其他隐式类型转换

    数组转换成指针

    数组是自动转换成指向数组首元素的指针

    int ia[10];
    // 含有10个整数的数组
    int* p = ia;
    // ia转换成指向数组首元素的指针

    decltype、&、sizeof、typeid等运算符操作时,上述转换不会发生

    如果用一个引用来初始化数组,上述转换也不会发生。

    指针的转换

    常量整数值或字面值nullptr能转换成任意指针类型

    指向任意非常量的指针能转换成void*

    指向任意对象的指针能转换成const void*

    还存在继承类型关系间的指针转换

    转换成布尔类型

    如果指针或算术类型的值为0,转换结果是false。

    转换成常量

    允许将指向非常量类型的指针转换成指向相应的常量类型的指针,对于引用也是这样。

    如果T是一种类型,我们就能将指向T的指针或引用分别转换成指向const T的指针或引用。

    int i;
    const int &j = i;
    // 非常量转换成const int的引用
    const int *p = &i;
    // 非常量的地址转换成const的地址
    int &r = j, *q = p;
    // 错误,不允许const转换成非常量

    相反的转换不存在,因为它试图删除掉底层const

    类类型定义的转换

    类类型能定义由编译器自动执行的转换,不过编译器每次只能指向一种类类型的转换。

    string s, t  = "a value";
    // 字符串字面值转换成string类型

    显式转换

    显式将对象强制转换成另外一种对象

    强制类型转换如浮点数除法,

    int i, j;
    double slope = i / j;
    // 将i和/或j显式转换成double

    命名的强制类型转换

    cast-name<type>(expression);

    type: 转换的目标类型

    expression: 要转换的值

    如果type是引用类型,则结果是左值。

    cast-name: static_cast、dynamic_cast、const_cast、reinterpret_cast

    static_cast

    任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast

    double slope = static_cast<double>(j) / i;
    // 进行强制类型转换以便执行浮点数除法

    当需要把一个较大的算术类型赋值给较小的类型时,static_cast非常有用

    如果不使用static_cast则会给出警告信息,

    static_cast对于编译器无法自动执行的类型转换非常有用

    可以用static_cast找回存在于void*指针中的值。

    void* p = &d;
    // 任何非常量对象的指针都能存入void*
    
    double *dp = static_cast<double*>(p);
    // 正确,将void*转换回初始的指针类型

    在转换时要确保指针的值保持不变,也就是说强制转换的结果将与原始的地址值相等。

    const_cast

    const_cast只能改变运算对象的底层const

    const char *pc;
    char *p = const_cast<char*>(pc);

    对于常量对象转换成非常量对象的行为,我们一般称为去掉const性质。

    如果对象本身不是一个常量,使用强制类型转换获得写权限是合法的行为

    如果对象本身是一个常量,使用强制类型转换执行写操作就会产生未定义的后果。

    const char *cp;
    char *q = static_cast<char*>(cp);
    // 错误,static_cast不能转换掉const性质
    static_cast<string>(cp);
    // 正确:字符串字面值传换成string类型
    const_cast<string>(cp);
    // 错误:const_cast只改变常量属性

    reinterpret_cast

    reinterpret_cast常为运算对象的位模式提供较低层次上的重新解释

    int *ip;
    char *pc = reinterpret_cast<char*>(ip);
    // pc所指的真实对象是一个int而非字符,如果把pc当作普通的字符指针使用就可能在运行时发生错误
    string str(pc);
    // 导致异常
  • 相关阅读:
    hibernate更新
    让hibernate支持mysql的text或者longtext
    hibernate的查询
    微博获取原图时重定向到图片的url
    java判断字符串编码
    爬取微博存入数据库时出错
    循环监听事件出错,只能监听最后一个
    org.hibernate.AssertionFailure: null id don't flus
    eclipse有时候导入了包,但是还是有红线,找不到
    hibernate注解创建表总是失败,显示表不存在
  • 原文地址:https://www.cnblogs.com/immjc/p/8044220.html
Copyright © 2011-2022 走看看