湖南省网站建设,谷歌seo算法规则,建e网室内设计网手机版,网站建设在哪里【摘要】 RTTI(Run-Time Type Identification)是面向对象程序设计中一种重要的技术。现行的C标准对RTTI已经有了明白的支持。只是在某些情况下出于特殊的开发须要#xff0c;我们须要自己编码来实现。本文介绍了一些关于RTTI的基础知识及其原理和实现#xff0c;并分析… 【摘要】 RTTI(Run-Time Type Identification)是面向对象程序设计中一种重要的技术。现行的C标准对RTTI已经有了明白的支持。只是在某些情况下出于特殊的开发须要我们须要自己编码来实现。本文介绍了一些关于RTTI的基础知识及其原理和实现并分析比較三者是线上的差异与联系。 【正文】 RTTI 的需求 和非常多其它语言一样C是一种静态类型语言。其数据类型是在编译期就确定的不能在执行时更改。然而因为面向对象程序设计中多态性的要求C中的指针或引用(Reference)本身的类型可能与它实际代表(指向或引用)的类型并不一致。有时我们须要将一个多态指针转换为事实上际指向对象的类型。就须要知道执行时的类型信息。这就产生了执行时类型识别的要求。C对RTTI的支持 C提供了两个keywordtypeid和dynamic_cast一个类type_info来支持RTTI。 dynamic_cast操作符它同意在执行时刻进行类型转换从而使程序可以在一个类层次结构安全地转换类型。dynamic_cast提供了两种转换方式。把基类指针转换成派生类指针或者把指向基类的左值转换成派生类的引用。见下例讲述 void company::payroll(employee *pe) {
//对指针转换失败dynamic_cast返回NULL
if(programmer *pmdynamic_cast(pe)){
pm-bonus();
}
}void company::payroll(employee re) {
try{
//对引用转换失败的话则会以抛出异常来报告错误
programmer rmdynamic_cast(re);
pm-bonus();
}
catch(std::bad_cast){
}
} 这里bonus是programmer的成员函数基类employee不具备这个特性。所以我们必须使用安全的由基类到派生类类型转换识别出programmer指针。 typeid操作符它指出指针或引用指向的对象的实际派生类型。 比如employee* penew manager;
typeid(*pe)typeid(manager) //true typeid能够用于作用于各种类型名对象和内置基本数据类型的实例、指针或者引用当作用于指针和引用将返回它实际指向对象的类型信息。typeid的返回是type_info类型。 type_info类这个类的确切定义是与编译器实现相关的。以下是《C Primer》中给出的定义(參考资料[2]中谈到编译器必须提供的最小信息量)class type_info {
private:
type_info(const type_info);
type_info operator( const type_info );
public:
virtual ~type_info();
int operator( const type_info ) const;
int operator!( const type_info ) const;
const char* name() const;
}; 详见http://bbs.csdn.net/topics/40414128 三者比較 宏能够在编译前用字符替换的办法展开减轻程序猿反复编码的工作量。c的范型模版也是在编译时确定终于的程序样式。他用的办法是编译时确定类型信息。RTTI是执行期类型信息能够在执行时得到对象的类型信息。我们考察一个程序为了说明问题我特意找了一个简单的程序这个程序比較a和b假设a大于b就交换他们。可是。a、b的类型并不确定可能是字符串也可能是整数还可能是复数。为了简洁和不至于造成过的混淆我不使用操作符重载。假定不论什么操作都是基于对象方法的为了完毕这个函数。a、b必须支持compare比較和swape交换方法。我们不清楚a、b的类型假设有3种类型我们就必须写3个函数吗那太累人了。我们用宏来定义这个函数好了。#define exchange(a,b) if(a.compare(b))a.swape(b);这样我们在使用的时候就能够直接使用exchange宏来表达这个函数并且能够适应各种类型仅仅要他们都支持这两个函数就能够。我们还能够用范型来实现这个函数templatetypename Tvoid exchange(T a, T b){ if(a.compare(b))a.swape(b)}我们相同达到了目的。假设编译器支持丰富的RTTI我们还能够用脚本语言的方式来实现他们。exchange(a, b){ if(a.compare(b))a.swape(b);}上面三种方式区别在哪里呢第一种。使用字符替换的方式在编译前展开宏使之成为程序中的一段代码。另外一种在编译时。确定调用函数的參数的类型并自己主动生成一个这个类型的暂时函数。第三种。在执行时依据參数的类型确定是否可以执行这段程序。前2种都是在编译时确认的。第三种是在执行时确定的。在程序设计中有着大量的反复代码我们须要一种方法来提高效率可是为什么看着结构类似的程序须要反复代码呢最重要的原因是传统的程序中实体函数、变量、属性等等在编译时都须要内存中一块确定的地址或者相对基址的偏移来指代。这时cpu处理方式的内在要求而这个和程序设计时依照名字引用的思维习惯是不一致的。我们能够用宏和模版来取代手工对每一个类型的特化可是在程序中仍然是使用地址来指代实体的。实际上每一个类型的特化程序依旧存在仅仅是在程序设计外观上不可见了。第三种方式。使用RTTI。程序中的实体都不再是确定的地址来指代而是通过字符串名称或者实体表来指代在执行时依据名称来特化。这样的方法和前2个方法是本质的不同。使用RTTI能够在非常大程度上减轻宏和静态模版带来的副作用使程序具有更加优雅的外观。可是。C的宏和静态模版也不是一无是处。他用在对效率更加严格场合是很合适的。 转载于:https://www.cnblogs.com/llguanli/p/8286541.html