不同数据类型之间的转换

不同数据类型之间的转换数据类型转换之隐式转换 显示转换 一 隐式类型转换 标准转换 1 算术转换 在混合类型的表达式中 以最宽的数据类型为目标转换类型 如 int a 3 double b 1 12 表达式 a b a 被转换为 double 类型 2

大家好,我是讯享网,很高兴认识大家。

数据类型转换之隐式转换、显示转换

一、隐式类型转换(标准转换)

1、算术转换

在混合类型的表达式中,以最宽的数据类型为目标转换类型,如:

int a = 3; double b = 1.12; //表达式 a+b a被转换为double类型 

讯享网

2、赋值转换

  • 直接赋值
    一种类型的表达式赋值给另外一种类型的对象:将会转换为被赋值对象的类型,如:
    讯享网int a = 3; double b = 1.12; a = b;//b从double转换为int 类型 
  • 函数传参赋值
    将一个表达式或者一个变量作为实参,传递给函数调用时,实参形参类型不一致,将会转换为形参类型,如:
    int fun(int a,int b) { 
          return a + b; } int main() { 
          double a = 3.14; double b = 1.12; cout << fun(a, b) << endl;//将double类型转换为int return 0; } 
  • 函数返回值赋值
    从一个函数返回一个表达式,表达式类型与返回类型不一致时,目标转换类型为函数的返回类型,如:
    讯享网int fun(double a,double b) { 
          return a + b;//传入参数为double,返回值为int,将double类型转换为int } int main() { 
          double a = 3.14; double b = 1.12; cout << fun(a, b) << endl;//将double类型转换为int return 0; } 

注意:void 指针赋值给其他指定类型的指针时,不存在标准转换,编译出错

void* p = 0;//0从int类型转换到了void *类型 int* b = p;//报错 

二、显示类型转换(强制类型转换)

通用语言风格:(type-id)A // 将A转化为type-id类型
C++语言风格:标准的C++四类类型转换(static_cast、dynamic_cast、reinterpret_cast、const_cast)

1、static_cast

  • 用法:
    static_cast<type_id>(expression)
  • 说明
    将 expression 转换为 type_id 类型,但没有运行时类型检查来保证转换的安全性
  • 为什么需要static_cast强制类型转换?
    • void指针->其他类型指针
    • 改变通常的标准转换
    • 避免出现可能多种转换歧义
  • 常见用法
    • 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
    • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证
    • 把void指针转换成目标类型的指针(不安全!!)
    • 任何类型的表达式转换成void类型。

注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

2、dynamic_cast

  • 用法
    dynamic_cast<type_id>(expression)
  • 说明
    该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
  • 主要用途
    • 当无法使用virtual函数的时候可以用dynamic_cast解决
    • 主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换,在进行上行转换时,它和static_cast的效果一样,进行下行转换时,dynamic_cast具有类型检查功能比static_cast更安全,如:
    讯享网class A { 
          public: int name; virtual void fun(); }; class B :public A { 
          public: char* namesize[100]; }; void foo(A *p) { 
          B* p1 = static_cast<B*>(p); B* p2 = dynamic_cast<B*>(p); } 
    对上面代码解释:如果p实际指向B类的对象,则p1 ,p2是一样的,并且对这两个指针执行B类型的任何操作都是安全的。
    如果P指向的是一个A类对象,那么p1将是一个指向该对象的指针,对它进行B类型的操作将是不安全的(如访问namesize),而p2将是一个空指针(即0,因为dynamic_cast失败)。
    另外注意:A要有虚函数,否者会编译出错,static_cast则没有这个限制。这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表里,只有定义了虚函数的类才有虚函数表。
    • 交叉转换,如:
    class A { 
          public: int name; virtual void fun(); }; class B1 :public A { 
          }; class B2 :public A { 
          }; void foo() { 
          B1* p1 = new B1; p1->name = 100; B2* p2 = static_cast<B2*>(p1);//编译出错 B2* p2 = dynamic_cast<B2*>(p1);//p2是空指针 } 

3、reinpreter_cast

  • 用法
    reinpreter_cast<type-id>(expression)
  • 说明
    type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。

4、const_cast

  • 用法
    const_cast<type_id> (expression)


    讯享网

  • 说明
    该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。

    常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

    讯享网class A { 
          public: int name; }; void foo() { 
          const A a1; a1.name = 100;//编译出错 A a2 = const_cast<A>(a1); a2.name = 100; } 

    上面的代码编译时会报错,因为a1是一个常量对象,不能对它进行改变;使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:a1和a2是两个不同的对象。

投稿来自 东北石油大学 - 计科202 - 刘记仪

小讯
上一篇 2025-01-05 16:45
下一篇 2025-04-02 11:27

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/27278.html