类型识别

静态类型:指针变量自身的类型

动态类型:指针所指向对象的类型

Parent* p_p = new Child();
Parent& q_p = p_p;
//Parent*是p_p的静态类型,Child()时p_p的动态类型。
//Parent&是q_p的静态类型

子类指针是否可以强制转换取决于对象的动态类型。

如何确定对象的动态类型:多态。

  1. 在基类中实现返回类型的虚函数。

  2. 所有派生类必须实现返回类型的虚函数。

  3. 每个类型的虚函数的实现必须不同。

实现如下:

#include <iostream>
#include <string>

using namespace std;

class Base
{
public:
    virtual string type()  // 定义虚函数
    {
        return "Base";
    }
};

class Derived1 : public Base
{
public:
    string type()    // 继承得到虚函数属性
    {
        return "Derived1";
    }
};

class Derived2 : public Base
{
public:
    string type()    // 继承得到虚函数属性
    {
        return "Derived2";
    }
};

void test(Base* b)
{
    if( b->type() == "Derived1"  ||  b->type() == "Derived2"  )
    {
        Derived* d = static_cast<Derived*>(b);  //  子类指针只能指向子类,不可指向父类
                                                //   父类指针可以指向子类或父类
        d->printf();
    }   
    // cout << dynamic_cast<Derived*>(b) << endl;
}

int main(int argc, char *argv[])
{
    Base b;
    Derived1 d1;
    Derived2 d2;
    
    test(&b); // 失败
    test(&d1);
    test(&d2); 
return 0; }

C++中用关键字typeid获取类型信息:返回一个对象type_info,对象包含类型信息,当参数是NULL时抛出异常

使用方法:const type_info& td = typeid(oject);

注意:参数为类型时:返回静态类型信息

   参数为变量时:变量内部没有虚函数表,返回静态信息。变量内部有虚函数表,返回动态类型信息。

#include <iostream>
#include <string>
#include <typeinfo>

using namespace std;

/************** 有虚函数的类 **************/

class Base_vir
{
public:
    virtual ~Base_vir()
    {
    }
};

class Derived_vir : public Base_vir
{
public:
};

/************** 没有虚函数的类 **************/
class Base
{
public:
     ~Base()
    {
    }
};

class Derived : public Base
{
public:
};

void test_vir(Base_vir* b)
{
    const type_info& tb = typeid(*b);
    cout << tb.name() << endl;
}

void test(Base* b)
{
    const type_info& tb = typeid(*b);
    cout << tb.name() << endl;
}

int main(int argc, char *argv[])
{
    int i = 0;
    
    const type_info& ty_i = typeid(i);
    const type_info& tii = typeid(int);
    cout << ty_i.name() << endl;   //静态类型 type_info.name = i 
    
    Base_vir b_vir;
    Derived_vir d_vir;
    test_vir(&b_vir);  // 动态类型,类型为父类   type_info.name = 4Base
    test_vir(&d_vir);  // 动态类型,类型为子类   type_info.name = 7Derived
    
    Base b;
    Derived d;
    test(&b);  // 静态类型,类型为父类  type_info.name = 4Base  
    test(&d);  // 静态类型,类型为父类   type_info.name = 4Base
    return 0;
}
原文地址:https://www.cnblogs.com/zsy12138/p/10870130.html