您的位置:首页 > 其它

RTTI 运行阶段类型识别

2016-01-18 19:11 363 查看
//RTTI只适合于包含虚函数的类,原因在于只有对于这种类层次的结构,才应该将派生类对象的地址赋给基类指针
/*RTTI的三种策略:
1. dynamic_cast  :
如果用于检测指针: Type *pm = dynamic_cast<Type *>(pt)
用法:pt的类型是否可以被安全转化为Type * ?如果可以,则返
回对象的地址,否则返回NULL

如果用于检测引用 :Type & rs =dynamic_cast<Type &> (rs)
用法:当类型不匹配导致的引用失败时,会引发  bad_cast 的异常
这种异常是从exception类派生而来的,定义于typeinfo头文件
例如:
try{
Superb &rs =dynamic_cast<Superb &> (rs);
...
}
catch (bad_cast &){
...
};

2. typeid        :    typeid(Magnificent) == typeid(*pg)  判断是真还是假
如果pg是一个空指针,程序将引发 bad_typeid 异常

3. type_info     :typeid 运算符返回一个type_info对象的引用,其中,type_info类是定义在
typeinfo 头文件中的一个类,type_info类 重载了 == 和 != 运算符
可以使用这些运算符来对类型进行比较

*/
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<typeinfo>

using namespace std;

class Grand
{
private:
int hold;

public:
Grand(int h=0):hold(h){}
virtual void Speak() const{
cout<<"I am a Grand Class!"<<endl;
}
virtual int Value()const {return hold;}
};

class Superb:public Grand
{
public:
Superb(int h=0):Grand(h) {}
void Speak() const{
cout<<"I am a Superb Class!"<<endl;
}
virtual void Say() const{
cout<<"I hold the Superb Value of :"<<Value()<<"!"<<endl;
}
};

class Magnificent:public Superb
{
private:
char ch;
public:
Magnificent(int h=0,char c='A') :Superb(h),ch(c){}
void Speak()const{
cout<<"I am a Magnificent Class!"<<endl;
}
void Say() const{
cout<<"I hold the character :"<<ch<<" and the integer "<<Value()<<"!"<<endl;
}
};

Grand * Getone();

int main(void){
std::srand(std::time(0));
Grand  * pg;
Superb * ps;
for(int i=0;i<5;i++){
pg=Getone();
//	cout<<"The type is :"<< typeid(*pg).name()<<"   ";  /*输出pg所指向的对象的类名*/
pg->Speak();
if(ps=dynamic_cast<Superb *>(pg)){
ps -> Say();
}
else{
cout<<"将我的地址赋给 Superb 是不安全的"<<endl;
}
}
return 0;
}

Grand * Getone(){
Grand *p;
switch(std::rand()%3){
case 0:p=new Grand(std::rand()%100);
break;
case 1:p=new Superb(std::rand()%100);
break;
case 2:p=new Magnificent(std::rand()%100,'A'+std::rand()%26);
break;
}
return p;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: