类型识别在面向对象中可能出现下面的情况基类指针指向子类对象(赋值兼容性)基类引用成为子类对象的别名(赋值兼容性)静态类型 - 变量(对象)自身的类型【编译期可确定】动态类型 - 指针(引用)所指向对象的实际类型【运行时才可确定】void test(Base* b){ /** 危险的类型转换方式:无法确定实际指向的类型 / Derived d = static_cast<Derived*>(b);}基类指针是否可以强制类型转换为子类指针取决于动态类型!问题:C++ 中如何得到动态类型呢?动态类型识别解决方案 - 利用多态在基类中定义虚函数返回具体的类型信息所有的派生类都必须实现类型相关的虚函数每个类型中的类型虚函数都需要不同的实现编程实验: 动态类型识别#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){ /** 危险的转换方式 / // Derived d = static_cast<Derived*>(b); if( b->type() == “Derived” ) { Derived* d = static_cast<Derived*>(b); d->print(); } // cout << dynamic_cast<Derived*>(b) << endl;}int main(){ Base b; Derived d; Child c; test(&b); test(&d); test(&c); return 0;}输出:I’m a Derived.思考:dynamic_cast<Derived*>(b); 为什么不适用于这里呢?dynamic_cast 可以判断是否转换成功,但无法识别指针实际指向的类型多态解决方案的缺陷必须从基类开始提供类型虚函数所有的派生类都必须重写类型虚函数每个派生类的类型名必须唯一可维护性不够友好类型识别关键字C++ 提供了typeid 关键字用于获取类型信息typeid 关键字返回对象参数的类型信息typeid 返回一个 type_info 类对象当 typeid 的参数为 NULL 时将抛出一个异常typeid 关键字的使用void code(){ int i = 0; const type_info& tiv = typeid(i); const type_info& tii = typeid(int); cout << (tiv == tii) << endl;}typeid 的注意事项当参数为类型时: 返回静态类型信息当参数为变量时:不存在虚函数表 - 返回静态类型信息存在虚函数表 - 返回动态类型信息编程实验: typeid 类型识别#include <iostream>#include <string>#include <typeinfo>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); 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++】14Base7Derived输出【vc2010】1class Baseclass Derived输出【bcc】1BaseDerived注意: typeid 虽然是 C++ 关键字,但在不同的编译器下有不同的行为。(不要做某些类型的假设)小结C++ 中有静态类型和动态类型概念利用多态能够实现对象的动态类型识别typeid 是专用于类型识别的关键字typeid 能够返回对象的动态类型信息以上内容参考狄泰软件学院系列课程,请大家保护原创!