zoukankan      html  css  js  c++  java
  • C++四种强制转换

    C++的四种强制类型转换,所以C++不是类型安全的。分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast

    为什么使用C风格的强制转换可以把想要的任何东西转换成合乎心意的类型。那为什么还需要一个新的C++类型的强制转换呢?

    新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++中风格是static_cast<type>(content)。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。

    四种转换的区别:

    static_cast:可以实现C++中内置基本数据类型之间的相互转换。

    1
    int c=static_cast<int>(7.987);

    如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不一定包含虚函数

    class A
    {};
    class B:public A
    {};
    class C
    {};
     
    int main()
    {
        A* a=new A;
        B* b;
        C* c;
        b=static_cast<B>(a);  // 编译不会报错, B类继承A类
        c=static_cast<B>(a);  // 编译报错, C类与A类没有任何关系
        return 1;
    }

    const_cast: const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。

    reinterpret_cast: 有着和C风格的强制转换同样的能力。它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。

    dynamic_cast: 

    (1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

    (2)不能用于内置的基本数据类型的强制转换。

    (3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

    (4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

            B中需要检测有虚函数的原因

     

            这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,

            只有定义了虚函数的类才有虚函数表。

     (5)在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比               static_cast更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。

    参考例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    #include<iostream>
    #include<cstring>
    using namespace std;
    class A
    {
       public:
       virtual void f()
       {
           cout<<"hello"<<endl;
           };
    };
     
    class B:public A
    {
        public:
        void f()
        {
            cout<<"hello2"<<endl;
            };
     
    };
     
    class C
    {
      void pp()
      {
          return;
      }
    };
     
    int fun()
    {
        return 1;
    }
    int main()
    {
        A* a1=new B;//a1是A类型的指针指向一个B类型的对象
        A* a2=new A;//a2是A类型的指针指向一个A类型的对象
        B* b;
        C* c;
        b=dynamic_cast<B*>(a1);//结果为not null,向下转换成功,a1之前指向的就是B类型的对象,所以可以转换成B类型的指针。
        if(b==NULL)
        {
            cout<<"null"<<endl;
        }
        else
        {
            cout<<"not null"<<endl;
        }
        b=dynamic_cast<B*>(a2);//结果为null,向下转换失败
        if(b==NULL)
        {
            cout<<"null"<<endl;
        }
        else
        {
            cout<<"not null"<<endl;
        }
        c=dynamic_cast<C*>(a);//结果为null,向下转换失败
        if(c==NULL)
        {
            cout<<"null"<<endl;
        }
        else
        {
            cout<<"not null"<<endl;
        }
        delete(a);
        return 0;
    }

    相关资料参考网址:

    http://baike.baidu.com/view/1745213.htm

    http://read.newbooks.com.cn/info/161950.html

    (转载时请注明作者和出处。未经许可,请勿用于商业用途)
    更多文章请访问我的Blog: http://www.cnblogs.com/alexqdh
  • 相关阅读:
    认识hasLayout——IE浏览器css bug的一大罪恶根源 转
    web网站p教程 转
    可遇不可求的Question之SQLServer的INSERT ON DUPLICATE KEY UPDATE语法篇
    可遇不可求的Question之Protoc.exe无法编译proto文件篇
    python各个版本的下载地址
    可遇不可求的Question之WCF发布无法运行篇
    [转]理解JSON:3分钟课程
    可遇不可求的Question之Silverlight发布IIS设置篇
    可遇不可求的Question之C#中的匿名事件导致内存泄露的解决篇
    可遇不可求的Question之mysql连接数暴增的解决方法篇
  • 原文地址:https://www.cnblogs.com/ymy124/p/3643562.html
Copyright © 2011-2022 走看看