详解c++中的类型识别

2020-06-30 11:00:33丽君

(2)利用 dynamic_cast

  1)dynamic_cast这个关键字如果要转换的实际类型和指定的类型不一样,则会返回NULL。例如当指定类型为子类对象时,如果父类指针的动态类型是这个子类对象时,转换成功,而动态类型是父类对象或者其他子类对象时,转换失败;

  2)dynamic_cast 要求使用的目标对象类型必须是多态,即:所在类族至少有一个虚函数;

  3)只能用于指针和引用之间的转换

    1.用于指针转换时,转换失败,返回空指针;

    2.用于引用转换时,转换失败,将引发 bad_cast异常。

 #include <iostream>
 #include <string>
 
 using namespace std;
 
 class Base
 {
 public:
   virtual ~Base()
   {
   
   }
 };
 
 class Derived : public Base
 {
 public:  
   void print()
   {
     cout << "I'm a Derived. " << endl;
   }
 };
 
 class Child : public Base
 {
 
 };
 
 void test(Base* pb)
 {
   // dynamic_cast 只能确定最终的转化结果,无法获取动态类型的原型
   Derived* pd = dynamic_cast<Derived*>(pb);
   
   if(pd != NULL)
   {
     // Derived 类类型, 可以使用指针pd访问Derived类的成员
     cout << "& = " << pd << endl;
     pd->print();
   }
   else
   {
     Child* pc = dynamic_cast<Child*>(pb);
     
     if(pc != NULL)
     {
       // Child 类类型, 可以使用指针pc访问Child类的成员
       cout << "& = " << pc << endl;
       cout << "I'm a Child. " << endl;
     }
     else
     {
       // Base 类类型, 可以使用指针pb访问Base类的成员
       cout << "& = " << pc << endl; 
       cout << "I'm a Base. " << endl;
     }
   }
 }
 
 int main(int argc, char *argv[])
 {
   Base b;
   Derived d;
   Child c;
   
   test(&b);
   test(&d);
   test(&c);
   
   return 0;
 }
 /**
 * 运行结果:
 * & = 0
 * I'm a Base. 
 * & = 0x7ffccf0dd860
 * I'm a Derived.
 * & = 0x7ffccf0dd870
 * I'm a Child.
 */

(3)利用 typeid(推荐这种方法)

  1)typeid是一个关键字,专门用于动态类型识别;

  2)typeid 关键字返回对应参数的类型信息,此类型信息是一个type_info类对象;

    1.当参数为类型时,返回静态类型信息;

    2.当参数为变量时:1> 参数变量内部不存在虚函数表时,返回静态类型信息; 2> 参数变量内部存在虚函数表时,返回动态类型信息;

    3.当参数为 NULL 时,将抛出异常;

  3)typeid使用时需要包含头文件<typeinfo>;

  4)typeid 使用时直接指定对象或者类型。

  5)typeid 在不同的编译器内部实现是不同的;

int i = 0;

const type_info& tiv = typeid(i); // 将 i 的类型信息放到 type_info 中去;
const type_info& tii = typeid(int);

cout << (tiv == tii) << endl; // 1