c/c++语言开发共享c++中的类型转换

目录 1. 隐式类型转换 2. 强制类型转换( static_cast、const_cast、reinterpret_cast、dynamic_cast) 3. 类型转换函数、转换构造函数 类型转换可分为 隐式类型转换(编译器自动完成) 与 强制类型转换(需要自己操作)。 隐式类型转换 基本数据类型 …


目录

 

  类型转换可分为 隐式类型转换(编译器自动完成) 与 强制类型转换(需要自己操作)。

隐式类型转换  

  基本数据类型之间会进行隐式的类型安全转换。其转换规则如下:

  c++中的类型转换

   我们用 1个案列来介绍这种隐式类型转换规则,会有意想不到的结果发生….!!!

 1 #include <iostream>  2 #include <string>  3   4 using namespace std;  5   6 int main()  7 {     8     short s = 'a';  9     unsigned int ui = 1000; 10     int i = -2000; 11     double d = i; 12      13     cout << "d = " << d << endl; 14     cout << "ui = " << ui << endl; 15     cout << "ui + i = " << ui + i << endl; 16      17     if( (ui + i) > 0 )  // 变量i会进行隐式类型转换 -> unsigned int  // ui + i > 0 18     { 19         cout << "positive" << endl; 20     } 21     else 22     { 23         cout << "negative" << endl; 24     } 25      26     cout << "sizeof(s + 'b') = " << sizeof(s + 'b') << endl;    // 4 // s -> int  'b' -> int // sizeof(s + 'b') = sizeof(int) // 编译器默认是int运算 27      28     return 0; 29 } 30 /* 31     d = -2000 32     ui = 1000 33     ui + i = 4294966296 34     positive 35     sizeof(s + 'b') = 4 36 */

  在c++中,还有其它几种隐式类型转换(后续讲解),那么现在试想一下这几个问题:

    1. 基本类型 可以转换为 类类型吗?— 可以,见转换构造函数;

    2. 类类型 可以转换为 基本类型吗?— 可以,见类型转换函数;

    3. 类类型之间可以转换吗?— 可以,见转换构造函数 和 类型转换函数;

  注:这种隐式类型转换不能够抑制,并且也是bug的来源之一;

强制类型转换

  在介绍c++强制类型转换前,我们可以回顾一下c语言中的强制类型转换。c语言中的强制类型转换十分简单、粗暴,即 (type)(expression);或者 type(expression);但是,这种简单的强制类型转换引发了很多问题,可归纳为如下2点:

  1. 任意类型之间都可以进行转换,编译器很难判断其正确性(过于粗暴);

  2. 在源码中无法快速定位所有使用强制类型转换的语句(很难定位);

所以,基于这2点考虑,在c++中引入了新式类型转换( static_castconst_castreinterpret_castdynamic_cast),其使用方法可归纳为 xxx_cast<type>(expression)

1、static_cast

  1. 用于 基本类型间的转换

  2. 不能用于基本类型指针间的转换

  3. 用于有继承关系类对象之间的转换和类指针之间的转换

  4. 用于 其它类型(基本类型和类类型) 向 类类型之间的转换;static_cast<类类型>(其它类型),见转换构造函数。

2、 const_cast

  1. 用于去除变量的只读属性

  2. 强制转换的目标类型必须是指针或引用

3、 reinterpret_cast

  1. 用于指针类型间的强制转换

  2. 用于整数和指针类型间的强制转换

4、 dynamic_cast

  1. 用于有继承关系的类指针(引用)间的转换

  2. 用于有交叉关系的类指针(引用)间的转换

  3. 相关类(基类)中必须有虚函数的支持

  4. 具有类型检查的功能,但类型转换的结果只可能在运行阶段得到;

  指针转换:

    转换成功:得到目标类型的指针;

    转换失败:得到一个空指针;

  引用转换: 

    转换成功:得到目标类型的引用;

    转换失败:得到一个异常操作的信息;

  dynamic_cast 转换时错误提示:

    1. 不能将父类指针 直接 转换为 子类指针

      c++中的类型转换

      c++中的类型转换  

     2. 在 父类中没有虚函数,不能发生多态 polymorphic

      c++中的类型转换

       c++中的类型转换

 1 #include <stdio.h>  2   3 void static_cast_demo()  4 {  5     int i = 0x12345;  6     char c = 'c';  7     int* pi = &i;  8     char* pc = &c;  9      10     c = static_cast<char>(i); 11     pc = static_cast<char*>(pi);    // error static_cast 不能用于基本类型指针之间 的转换 12 } 13  14 void const_cast_demo() 15 { 16     const int& j = 1; 17     int& k = const_cast<int&>(j); 18      19     const int x = 2; 20     int& y = const_cast<int&>(x); 21      22     int z = const_cast<int>(x);     // error const_cast 强制转换的目标类型必须是指针或引用类型 23      24     k = 5; 25      26     printf("k = %dn", k);  // 5 27     printf("j = %dn", j);  // 5 28      29     y = 8; 30      31     printf("x = %dn", x);  // 2 32     printf("y = %dn", y);  // 8 33     printf("&x = %pn", &x);// 0x7fffd40b84e8 34     printf("&y = %pn", &y);// 0x7fffd40b84e8 35 } 36  37 void reinterpret_cast_demo() 38 { 39     int i = 0; 40     char c = 'c'; 41     int* pi = &i; 42     char* pc = &c; 43      44     pc = reinterpret_cast<char*>(pi); 45     pi = reinterpret_cast<int*>(pc); 46     pi = reinterpret_cast<int*>(i); 47     c = reinterpret_cast<char>(i);  // error reinterpret_cast 适用于指针类型之间的转换  和 整型与指针类型之间的转换 48 } 49  50 void dynamic_cast_demo() 51 { 52     int i = 0; 53     int* pi = &i; 54     char* pc = dynamic_cast<char*>(pi); // error 55 } 56  57 int main() 58 { 59     static_cast_demo(); 60     const_cast_demo(); 61     reinterpret_cast_demo(); 62     dynamic_cast_demo(); 63      64     return 0; 65 }

 

 1 #include <iostream>  2 #include <string>  3   4 using namespace std;  5   6 class base  7 {  8 public:  9     base() 10     { 11         cout << "base::base()" << endl; 12     } 13      14     virtual ~base() 15     { 16         cout << "base::~base()" << endl; 17     } 18 }; 19  20 class derived : public base 21 { 22 public: 23     derived() 24     { 25         cout << "derived::derived()" << endl; 26     } 27      28     void func() 29     { 30         cout << "derived::func()" << endl; 31     } 32      33     virtual ~derived() 34     { 35         cout << "derived::~derived()" << endl; 36     } 37 }; 38  39 void test1() 40 { 41     base* bp = new derived(); 42      43     derived *dp = dynamic_cast<derived*>(bp);   // 当父类指针指向的是子类对象,转换成功 44     //derived *dp = static_cast<derived*>(bp);  // 当父类指针指向的是子类对象,转换成功 45     if( dp != null ) 46     { 47         cout << "dp = " << dp << endl; 48         dp->func(); 49     } 50     else 51     { 52         cout << "cast error!" << endl; 53     } 54      55     delete bp; 56 } 57  58 void test2() 59 { 60     base* bp = new base(); 61      62     derived *dp = dynamic_cast<derived*>(bp);   // 转化失败,不能将父类指针对象转换为子类指针对象 63     //derived *dp = static_cast<derived*>(bp);     // 转换成功,可以将父类指针对象转换为子类指针对象 64     if( dp != null ) 65     { 66         cout << "dp = " << dp << endl; 67         dp->func(); 68     } 69     else 70     { 71         cout << "cast error!" << endl; 72     } 73      74     delete bp; 75 } 76  77 int main() 78 { 79     test1(); 80      81     cout << "-----------------------" << endl; 82      83     test2(); 84  85     return 0; 86 }

  通过 《 static_cast 与 dynamic_cast 测试案列 》可知,当使用 dynamic_cast 强制类型转换时,即 derived *dp = dynamic_cast<derived*>(bp); 程序的运行结果为:

          c++中的类型转换

   当使用 static_cast 强制类型转换时,即 derived *dp = static_cast<derived*>(bp); 程序的运行结果为:

         c++中的类型转换

  从运行结果可知, static_cast 与 dynamic_cast 在继承中进行类指针转换时是存在差异的;其中,

    1. 相同点:当父类指针 指向 子类对象时,二者都可以将父类指针 成功转换为 子类指针;

      c++中的类型转换

     2. 不同点:当父类指针 指向 父类对象时,

      1) static_cast 转换:可以将父类指针 成功转换为 子类指针;

      2)dynamic_cast 转换:父类指针 不能够转换为  子类指针;

      c++中的类型转换 

类型转换函数

1、转换构造函数

  当构造函数只有1个参数 参数的类型是基本类型 或者是 其它类型时,就是转换构造函数。其作用是将其他类型 转换为 类类型

  编译器尽力尝试的结果是隐式类型转换,隐式类型转换是工程中bug的重要来源;

  工程中通过explicit关键字杜绝隐式转换,转换构造函数被explicit修饰时只能进行显示转换;

  转换方式

  1. static_ cast<classname >(value);

  2. classname(value);

  3. (classname)value; //不推荐

  在类型转换时调用转换构造函数。

         c++中的类型转换

 1 #include <iostream>  2 #include <string>  3   4 using namespace std;  5   6 class test  7 {  8     int mvalue;  9 public: 10     test() 11     { 12         mvalue = 0; 13     } 14      15     explicit test(int i) 16     { 17         mvalue = i; 18     } 19      20     test operator + (const test& p) 21     { 22         test ret(mvalue + p.mvalue); 23          24         return ret; 25     } 26      27     int value() 28     { 29         return mvalue; 30     } 31 }; 32  33 int main() 34 {    35     test t; 36     test r; 37      38     // 隐式类型转换 不加explicit关键字 39     //t = 5;        // t = test(5); 40     //r = t + 10;   // r = t + test(10); 41      42     t = static_cast<test>(5);    // t = test(5);     43     r = t + static_cast<test>(10);   // r = t + test(10); 44      45     cout << r.value() << endl;  // 15 46      47     return 0; 48 }

 2、类型转换函数

   c++ 中可以定义类型转换函数,其作用是将 类类型 转换为 其它类型;其语法格式为:

1 // 类型转换函数语法格式 2 operator type() 3 { 4      type ret; 5  6      // ... 7    8      retuan type; 9 }

  编译器能够隐式的使用类型转换函数

 c++中的类型转换

 1 #include <iostream>  2 #include <string>  3   4 using namespace std;  5   6 class test  7 {  8     int mvalue;  9 public: 10     test(int i = 0) 11     { 12         mvalue = i; 13     } 14     int value() 15     { 16         return mvalue; 17     } 18     operator int () 19     { 20         return mvalue; 21     } 22 }; 23  24 int main() 25 {    26     test t(100); 27     int i = t;  // 隐式的使用类型转换函数 operator int () 28      29     cout << "t.value() = " << t.value() << endl;    // t.value() = 100 30     cout << "i = " << i << endl;    // i = 100 31      32     return 0; 33 }

3、类型转换函数  vs  转换构造函数 

  结论:

  1. 类型转换函数 与 转换构造函数 具有同等的地位

  2. 无法抑制隐式的类型转换函数调用,此时 类型转换函数可能与转换构造函数冲突(类类型之间的转换);

  3. 在类型转换时 调用类型转换函数 、转换构造函数。

  4. 工程中以type totype()的公有成员 代替 类型转换函数

    c++中的类型转换

 1 #include <iostream>  2 #include <string>  3   4 using namespace std;  5   6 class test;  7   8 class value  9 { 10 public: 11     value() 12     { 13     } 14     explicit value(test& t) 15     { 16         cout << "explicit value(test& t)" << endl; 17     } 18 }; 19  20 class test 21 { 22     int mvalue; 23 public: 24     test(int i = 0) 25     { 26         mvalue = i; 27     } 28     int value() 29     { 30         return mvalue; 31     } 32     operator value() 33     { 34         value ret; 35         cout << "operator value()" << endl; 36         return ret; 37     } 38 }; 39  40 int main() 41 {    42     test t(100); 43     value v1 = t;    // 隐式的调用类型转换函数 operator value() 44     value v2 = static_cast<value>(t);    // 显示的调用转换构造函数 explicit value(test& t) 45      46     return 0; 47 } 48 /* 49     运行结果: 50     operator value() 51     explicit value(test& t) 52 */

      //  类型转换函数与转换构造函数发生冲突   的示意图    

 c++中的类型转换          c++中的类型转换

 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/600338.html

(0)
上一篇 2021年5月9日
下一篇 2021年5月9日

精彩推荐