运行时类型识别
C++中有两种方法可以识别当前运行的类型信息
1、dynamic_cast,记得我们之前多态提及向上类型转换,试图用基类来调用子类的方法,当然了需要虚函数的辅助,其实类型的信息正是虚函数的第一个slot中的内容。使用该关键字实现的称为向下类型转换。
class Security
{
public:
virtual ~Security(){}
};
class Stock:public Security{};
class Bond:public Security{};
class Investment:public Security
{
public:
void special()
{
std::cout<<"special Investment function"<<std::endl;
}
};
class Metal:public Investment{};
int main()
{
vector<Security *>portfolio;
portfolio.push_back(new Metal);
portfolio.push_back(new Investment);
portfolio.push_back(new Bond);
portfolio.push_back(new Stock);
for (vector<Security *>::iterator it=portfolio.begin();it!=portfolio.end();++it)
{
Investment * cm=dynamic_cast<Investment *>(*it);
if (cm)
{
cm->special();
}
else
cout<<"not a Investment"<<endl;
}
cout<<"cast from intermediate pointer"<<endl;
Security * sp=new Metal;
Investment * cp=dynamic_cast<Investment * >(sp);
if (cp)
{
cout<<"it is an investment"<<endl;
}
Metal *mp=dynamic_cast<Metal*>(sp);
if (mp)
{
cout<<"it is a Metal too"<<endl;
}
}
运行结果:

从结果中我们可以发现dymatic_cast能够在多层的继承结构中将类型转换到中间类型。
2、typeid操作符
该操作符返回一个type_info常量对象的引用。当没有虚函数的时候,typeid返回基类地址。Dymatic_cast的开销比typeid大。如果p为指针,type(*p)返回的是派生类类型,typeid(p)返回基类类型。r 为引用类型,typeid(p)为派生类的,typeid(&p)为基类类型。
3、RTTI在编译时和运行时都会产生开销。取得指向虚函数表指针,得到type_info指针,产生一个对type_info结构的引用,双指针的解析。还要判断其基类。构造函数等,但是RTTI引入使得在加入新类型时,必须确定新加入的类型不会导致问题,因此这样的不确定性等都应该慎用这个技术。
4、不能对void指针进行映射,它就是无类型信息的。