zoukankan      html  css  js  c++  java
  • C++ 强制类型转换

    强制类型转换
    static_cast  interpret_cast
    const_cast   dynamic_cast


    1. static_cast
    static_cast用来进用行比较“自然”和低风险的转换,比如整型和实数型、字符型之间互相转换。
    static_cast不能来在不同类型的指针之间互相转换,也不能用于整型和指针之间的互相转换,也不能用于不同类型的引用之间的转换。

     1 #include <iostream>
     2 using namespace std;
     3 class A
     4 {
     5 public:
     6     operator int() { return 1; }
     7     operator char * (){ return NULL; }
     8 };
     9 int main()
    10 {
    11     A a;
    12     int n; char * p = "New Dragon Inn";
    13     n = static_cast<int>(3.14); // n 的值变为 3
    14     n = static_cast<int>(a); //调用a.operator int, n的值变为 1
    15     
    16     p = static_cast<char*>(a); //调用a.operator char *,p的值变为 NULL
    17     n = static_cast<int> (p); //编译错误, static_cast不能将指针转换成整型
    18     p = static_cast<char*>(n); //编译错误, static_cast不能将整型转换成指针
    19     return 0;
    20 }


    2. reinterpret_cast
    reinterpret_cast用来进行各种不同类型的指针之间的转换、不同类型的引用
    之间转换、以及指针和能容纳得下指针的整数类型之间的转换。转换的时候,
    执行的是逐个比特拷贝的操作。

     1 #include <iostream>
     2 using namespace std;
     3 class A
     4 {
     5 public:
     6     int i;
     7     int j;
     8     A(int n):i(n),j(n) { }
     9 };
    10 int main()
    11 {
    12     A a(100);
    13     int & r = reinterpret_cast<int&>(a); //强行让 r 引用 a
    14     r = 200; //把 a.i 变成了 200
    15     cout << a.i << "," << a.j << endl; // 输出 200,100
    16     int n = 300;
    17     
    18     A * pa = reinterpret_cast<A*> ( & n); //强行让 pa 指向 n
    19     pa->i = 400; // n 变成 400
    20     pa->j = 500; //此条语句不安全,很可能导致程序崩溃
    21     cout << n << endl; // 输出 400
    22     long long la = 0x12345678abcdLL;
    23     pa = reinterpret_cast<A*>(la); // la太长,只取低32位0x5678abcd拷贝给pa
    24     unsigned int u = reinterpret_cast<unsigned int>(pa); //pa逐个比特拷贝到u
    25     cout << hex << u << endl; //输出 5678abcd
    26     typedef void (* PF1) (int);
    27     typedef int (* PF2) (int,char *);
    28     PF1 pf1; PF2 pf2;
    29     pf2 = reinterpret_cast<PF2>(pf1); //两个不同类型的函数指针之间可以互相转换
    30 }
    31 //输出结果
    32 //200,100
    33 //400
    34 //5678abcd


    3. const_cast
    用来进行去除const属性的转换。将const引用转换成同类型的非const引用,
    将const指针转换为同类型的非const指针时用它。例如:
    const string s = “Inception”;
    string & p = const_cast<string&>(s);
    string * ps = const_cast<string*>(&s); // &s的类型是const string *

    4. dynamic_cast
    dynamic_cast专门用于将多态基类的指针或引用,强
    制转换为派生类的指针或引用,而且能够检查转换的
    安全性。对于不安全的指针转换,转换结果返回NULL
    指针。
    dynamic_cast不能用于将非多态基类的指针或引用,
    强制转换为派生类的指针或引用

     1 #include <iostream>
     2 #include <string>
     3 using namespace std;
     4 class Base
     5 { //有虚函数,因此是多态基类
     6 public:
     7     virtual ~Base() { }
     8 };
     9 class Derived:public Base { };
    10 int main()
    11 {
    12     Base b;
    13     Derived d;
    14     Derived * pd;
    15     pd = reinterpret_cast<Derived*> ( &b);
    16     
    17     if( pd == NULL) //此处pd不会为NULL。
    18         //reinterpret_cast不检查安全性,总是进行转换
    19         cout << "unsafe reinterpret_cast" << endl;
    20     //不会执行
    21     pd = dynamic_cast<Derived*> ( &b);
    22     if( pd == NULL)
    23         //结果会是NULL,因为 &b不是指向派生类对象,此转换不安全
    24         cout << "unsafe dynamic_cast1" << endl; //会执行
    25     Base * pb = & d;
    26     pd = dynamic_cast<Derived*> ( pb); //安全的转换
    27     if( pd == NULL) //此处pd 不会为NULL
    28         cout << "unsafe dynamic_cast2" << endl; //不会执行
    29     return 0;
    30 }
    31 //输出结果:
    32 //unsafe dynamic_cast1

    Derived & r = dynamic_cast<Derived&>(b);
    那该如何判断该转换是否安全呢?
    答案:不安全则抛出异常

    > ( &b);12if( pd == NULL) //此处pd不会为NULL。//reinterpret_cast不检查安全性,总是进行转换cout << "unsafe reinterpret_cast" << endl;//不会执行pd = dynamic_cast<Derived*> ( &b);if( pd == NULL)//结果会是NULL,因为 &b不是指向派生类对象,此转换不安全cout << "unsafe dynamic_cast1" << endl; //会执行Base * pb = & d;pd = dynamic_cast<Derived*> ( pb); //安全的转换if( pd == NULL) //此处pd 不会为NULLcout << "unsafe dynamic_cast2" << endl; //不会执行return 0;}输出结果:unsafe dynamic_cast113Derived & r = dynamic_cast<Derived&>(b);那该如何判断该转换是否安全呢?答案:不安全则抛出异常14In-Video Quiz以下哪段程序是编译不会出错的?A)struct A {}; struct B:public A {}; A * pa; B* pb; pb = dynamic_cast<B*> (pa);B)int * p = static_cast<int *> ("this");C)string s; int * p = reinterpret_cast<int *> (& s);D)unsigned u = static_cast<unsigned *> ("this");15In-Video Quiz以下哪段程序是编译不会出错的?A)struct A {}; struct B:public A {}; A * pa; B* pb; pb = dynamic_cast<B*> (pa);B)int * p = static_cast<int *> ("this");C)string s; int * p = reinterpret_cast<int *> (& s);

  • 相关阅读:
    Func<T>、Action<T> 的区别于说明
    Invoke()/BeginInvoke()区别
    C# Linq处理list数据
    C# 的三种序列化方法
    P3368 【模板】树状数组 2
    P2058 海港
    2019.6.24 校内测试 NOIP模拟 Day 2 分析+题解
    2019.6.20 校内测试 NOIP模拟 Day 1 分析+题解
    2019.6.18 校内测试 分析+题解
    P1310 表达式的值
  • 原文地址:https://www.cnblogs.com/wanderingzj/p/5345952.html
Copyright © 2011-2022 走看看