天天看点

C++编程思想——运行时类型识别

运行时类型识别

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;
	}
}
           

运行结果:

C++编程思想——运行时类型识别

从结果中我们可以发现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指针进行映射,它就是无类型信息的。