• 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更安全的原因。

  • 相关阅读:
    敏捷开发原则与实践(七)之接口隔离原则
    敏捷开发原则与实践(六)之依赖倒置原则
    敏捷开发原则与实践(五)之替换原则
    敏捷开发原则与实践(四)之开放-关闭原则
    敏捷开发原则与实践(三)之 单一职责原则
    敏捷开发原则与实践(二)
    ios 3DTouch基本使用教程
    ios 关于正则表达式
    ios 含有textfield的viewcontroller随键盘弹起而改变位置
    ios 图片库和相机选择图片界面修改为简体中文
  • 原文地址:https://www.cnblogs.com/Galesaur-wcy/p/15219300.html
Copyright © 2020-2023  润新知