zoukankan      html  css  js  c++  java
  • 第66课 C++中的类型识别

    1. 类型识别

    (1)在面向对象可能出现下面的情况

      ①基类指针指向子类对象

      ②基类引用成为子类对象别名

           

    静态类型——变量(对象)自身的类型(定义变量类型时类型或参数类型

    动态类型——指针(引用)所指向的对象的实际类型

     

    (2基类指针转子类指针

    ①示例:Derived* d = static_cast<Derived*>(pBase); //危险的转换方式

    ②问题:不安全基类指针是否可以强制类型转换子类指针取决动态类型

    2. 利用多态获取动态类型

    (1)解决方案

      ①在基类中定义虚函数,并返回具体的类型信息

      ②所有的派生类必须实现类型相关的虚函数

      ③每个类中的类型虚函数需要不同的实现

    【编程实验】动态类型识别  66-1.cpp

    #include <iostream>
    
    #include <string>
    
     
    
    using namespace std;
    
     
    
    class Base
    
    {
    
    public:
    
        //在基类中提供个用来判断类型的虚函数
    
        //并且所有的派生类中都必须实现这个函数
    
        virtual string type()
    
        {
    
            return "Base";  //手动返回一个用于识别的标识符
    
        }   
    
    };
    
     
    
    class Derived : public Base
    
    {
    
    public:
    
        string type()
    
        {
    
            return "Derived";
    
        }
    
     
    
        void print()
    
        {
    
            cout << "I'm a Derived." << endl;
    
        }
    
    };
    
     
    
    class Child : public Base
    
    {
    
    public:
    
        string type()
    
        {
    
            return "Child";
    
        }
    
    };
    
     
    
    void test(Base* b)
    
    {
    
        //危险的转换方式。因为b可能实际类型可能不是Derived的类型
    
        //Derived* d = static_cast<Derived*>(b);
    
        if(b->type() == "Derived")
    
        {
    
            Derived* d = static_cast<Derived*>(b);
    
            d->print();
    
        }
    
        //如果类中没有虚函数表,则调用dynamic_cast会直接报错,编译不过。
    
        //当父、子类没有继承关系时,dynamic_cast返回false,否则会转换后
    
        //实际对象的地址
    
        cout <<  dynamic_cast<Derived*>(b) << endl;
    
    }
    
     
    
    int main()
    
    {
    
        Base b;
    
        Derived d;
    
        Child c;
    
       
    
        test(&b);  //Base与Base没有继承关系,dynamic_cast返回false
    
        test(&d);  //Derived与Base有继承关系,dynamic_cast转换后对象的地址
    
        test(&c);  //Child与Derived没有继承关系,返回false
    
       
    
        return 0;
    
    }

    运行结果:

      

    (2)多态解决方案缺陷

      ①必须从基类开始提供类型虚函数

      ②所有的派生类必须重写类型虚函数

      ③每个派生类的类型名必须唯一

    3. 类型识别关键字:typeid获取类型信息

    (1)typeid关键字

    • typeid关键字返回对应参数类型信息

    • typeid返回一个type_info类的对象

    • typeid参数NULL抛出异常

    • 包含头文件#include<typeinfo>

    (2)typeid关键字的使用

    int i = 0;
    
    const type_info& tiv = typeid(i);   //得到变量i的类型信息
    
    const type_info& tii = typeid(int); //得到int类型信息

    (3)typeid的注意事项

      ①当参数为类型时返回静态类型信息

      ②当参数为变量时

        A.不存在虚函数表时:返回静态类型信息

        B.存在虚函数表时:返回动态类型信息

    【编程实验】typeid类型识别  66-2.cpp

    #include <iostream>
    
    #include <string>
    
    #include <typeinfo> //for typeid
    
     
    
    using namespace std;
    
     
    
    class Base
    
    {
    
    public:
    
        virtual ~Base(){}
    
    };
    
     
    
    class Derived : public Base
    
    {
    
    public:
    
        void print()
    
        {
    
            cout << "I'm a Derived." << endl;
    
        }
    
    };
    
     
    
    void test(Base* b)
    
    {   
    
        //const type_info& tb = typeid(b); //判断b的类型,Base*或Derived*
    
        const type_info& tb = typeid(*b);  //判断对象的类型
    
       
    
        cout << tb.name() << endl;
    
    }
    
     
    
    int main()
    {
    
        int i = 0;
    
    
        const type_info& tiv = typeid(i);    //判断变量的类型
    
        const type_info& tii = typeid(int);  //判断类的类型
    
        cout << (tiv == tii) << endl;  //相等
    
       
    
        Base b;
    
        Derived d;
    
    
        test(&b);
    
        test(&d);
      
    
        return 0;
    
    }

    运行结果:g++下类名前面的数字表示类名的长度

      

    4. 小结

    (1)C++中有静态类型动态类型概念

    (2)利用多态能够实现对象动态类型识别

    (3)typeid是专用于类型识别的关键字

    (4)typeid能够返回对象动态类型信息

  • 相关阅读:
    PHP设计模式之适配器模式
    PHP设计模式之注册模式
    PHP中 构造函数(__construct)和析构函数(__destruct)
    PHP中 extends、implements、abstract、interface 的区别
    proxysql
    安装xtrabackup并进行全量备份
    锁解析
    索引与算法
    约束
    show语句
  • 原文地址:https://www.cnblogs.com/hoiday/p/10211732.html
Copyright © 2011-2022 走看看