zoukankan      html  css  js  c++  java
  • C++中的类型转换——static_cast dynamic_cast

    原文链接:https://blog.csdn.net/baidu_35679960/article/details/80821222

    1、隐式转型(向上转型,即将派生类对象赋值给基类)
    C++允许向上转型,即将派生类的对象赋值给基类的对象是可以的,其只不过是将派生类中基类的部分直接赋给基类的对象,这称为向上转型(此处的“上”指的是基类),例如:

    class Base{ };
    class Derived : public base{ };
    Base* Bptr;
    Derived* Dptr;
    Bptr = Dptr; //编译正确,允许隐式向上类型转换
    Dptr = Bptr;//编译错误,C++不允许隐式的向下转型;

    但是编译正确不代表能够使得程序安全运行。这很好理解,如果你把一个指向Base类对象的指针 赋值 给一个Drived类类型的指针,如果这个指针去访问Drived类中存在而Base类中不存在成员,很明显就不安全了。
    所以一个更好的办法是使用dynamic_cast;

    2、向下转型
    正如上面所述,类层次间的向下转型是不能通过隐式转换完成的。此时要向达到这种转换,可以借助static_cast 或者dynamic_cast。

    2.1 通过static_cast完成向下转型
    例如:

    class Base{ };
    class Derived : public base{ };
    Base* B;
    Derived* D;
    D = static_cast<Drived*>(B); //正确,通过使用static_cast向下转型

    需要注意的是:static_cast的使用,当且仅当类型之间可隐式转化时,static_cast的转化才是合法的。有一个例外,那就是类层次间的向下转型,static_cast可以完成类层次间的向下转型,当时向下转型无法通过隐式转换完成!

    2.2 通过dynamic_cast完成向下转型
    和static_cast不同,dynamic_cast涉及运行时的类型检查。如果向下转型是安全的(也就是说,如果基类指针或者引用确实指向一个派生类的对象),这个运算符会传回转型过的指针。如果downcast不安全(即基类指针或者引用没有指向一个派生类的对象),这个运算符会传回空指针。
    ps:要使用dynamic_cast类中必须定义虚函数

    class Base{
    publicvirtual void fun(){}
    };
    class Drived : public base{
    public:
    int i;
    };
    Base *Bptr = new Drived();//语句0
    Derived *Dptr1 = static_cast<Derived *>(Bptr); //语句1;
    Derived *Dptr2 = dynamic_cast<Derived *>(Bptr); //语句2;

    此时语句1和语句2都是安全的,因为此时Bptr确实是指向的派生类,虽然其类型被声明为Base*,但是其实际指向的内容确确实实是Drived对象,所以语句1和2都是安全的,Dptr1和Dptr2可以尽情访问Drived类中的成员,绝对不会出问题。
    但是此时如果将语句0改为这样:

    Base *Bptr = new Base();


    那语句1就不安全了,例如访问Drived类的成员变量i的值时,将得到一个垃圾值。(延后了错误的发现)
    语句2使得Dptr2得到的是一个空指针,对空指针进行操作,将发生异常,从而能够尽早的发现错误,这也是为什么说dynamic_cast更安全的原因。

  • 相关阅读:
    红帽7 创建网络会话
    红帽7 Iptables与Firewalld防火墙
    红帽7 配置网卡
    红帽7 LVM逻辑卷管理器
    红帽7 RAID磁盘冗余阵列
    红帽7 磁盘划分
    wpf学习一(转)
    选中当前点击的位置
    c#客显
    两个程序间的通信有三种
  • 原文地址:https://www.cnblogs.com/Galesaur-wcy/p/15219300.html
Copyright © 2011-2022 走看看