解析C++中四种强制类型转换的区别详解

 更新时间:2013年05月16日 11:16:12   作者:  
本篇文章是对C++中四种强制类型转换的区别进行了详细的分析介绍,需要的朋友参考下
C++的四种强制类型转换,所以C++不是类型安全的。分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast
为什么使用C风格的强制转换可以把想要的任何东西转换成合乎心意的类型。那为什么还需要一个新的C++类型的强制转换呢?
新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++中风格是static_cast<type>(content)。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。
四种转换的区别:
static_cast:可以实现C++中内置基本数据类型之间的相互转换。
复制代码 代码如下:

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更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。
参考例子:
复制代码 代码如下:

#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;
}

相关文章

  • C语言入门篇--注释,关键字typedef及转义字符详解

    C语言入门篇--注释,关键字typedef及转义字符详解

    本篇文章是c语言基础篇,主要为大家介绍了C语言的关键字typedef,注释,转义字符的基本理论知识,希望可以帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08
  • C++实现LeetCode(191.位1的个数)

    C++实现LeetCode(191.位1的个数)

    这篇文章主要介绍了C++实现LeetCode(191.位1的个数),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++文件依存关系介绍

    C++文件依存关系介绍

    如果现在你做的C++项目(课题)包含的文件没有超过1000个,你可以选择略过此文,不过建议继续浏览
    2013-01-01
  • c++ vector模拟实现代码

    c++ vector模拟实现代码

    vector是C++ STL中一个非常重要的容器,了解 vector 的底层实现原理,可以很好的帮助我们更加熟练的使用vector。这篇文章通过实例代码给大家介绍c++ vector模拟实现,感兴趣的朋友跟随小编一起看看吧
    2020-02-02
  • 自己简单封装的一个CDialog类实例

    自己简单封装的一个CDialog类实例

    这篇文章主要介绍了自己简单封装的一个CDialog类,实例分析了自定义封装CDialog类的相关技巧,比较简单易懂,需要的朋友可以参考下
    2015-04-04
  • c/c++那些你一定会出错的数组笔试题汇总

    c/c++那些你一定会出错的数组笔试题汇总

    这篇文章主要给大家汇总介绍了关于c/c++那些你一定会出错的数组笔试题,除了基本数据类型之外,其余的都作为类对象,包括数组,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • 浅析c语言中的内存

    浅析c语言中的内存

    在c++中,内存分为5个区,分别是栈区,堆区,自由存储区,全局/静态存储区和常量存储区.
    2017-09-09
  • 使用单链表实现多项式计算示例

    使用单链表实现多项式计算示例

    这篇文章主要介绍了使用单链表实现多项式计算示例,需要的朋友可以参考下
    2014-03-03
  • C++深入刨析类与对象的使用

    C++深入刨析类与对象的使用

    类和对象是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型;变量就是可以变化的量,存储在内存中—个可以拥有在某个范围内的可变存储区域
    2022-05-05
  • rapidjson解析json代码实例以及常见的json core dump问题

    rapidjson解析json代码实例以及常见的json core dump问题

    今天小编就为大家分享一篇关于rapidjson解析json代码实例以及常见的json core dump问题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04

最新评论