RTTI 运行阶段类型识别

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








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值