为什么需要RTTI(运行时类型信息)?
答案 0 :(得分:11)
RTTI, 运行时类型信息 ,为C ++引入了[温和]反射形式。
它允许知道例如超类的类型,因此允许处理全部来自相同基类型的对象的异构集合。以特定于各个超类的方式。 (假设您有一个“车辆”对象数组,并且需要对阵列中找到的“卡车”对象进行不同的处理。)
RTTI是否 必要 这个问题是一个开放的问题。故事是Bjarne Stroustrup故意将此功能从原始C ++规范中排除,因为担心它会被滥用。
确实存在过度使用/滥用反射功能的机会,而这在C ++最初引入时可能更为重要,因为在主流程序员社区中没有这样的OOP文化。
这说,有了更多OOP精明的社区,有效地展示了反思可以做的所有好事(例如,使用Java或C#等语言)以及现在使用的花哨的设计模式,我坚信RTTI和反思即使有时被误用,一般的特征也非常重要。
答案 1 :(得分:3)
我可以想到一个使用RTTI的情况,它甚至不起作用。
执行回调的C兼容API通常提供用户定义的void *来将状态结构传回给调用者,这是很常见的。从C ++调用这样的API时,通过所述void *参数传递this指针是很常见的。从回调中,可能想要在传递的指针上调用虚函数。
在某些情况下,当回调参数不安全时(例如Windows消息的LPARAM),显然需要通过检查隐藏的vfptr来在将指针用于虚拟调用之前验证指针。 dynamic_cast
是执行此操作的自然方式,但在对象无效时会导致未定义的行为(IIRC,如果指针指向除具有虚拟表的对象之外的任何内容,则它是未定义的行为)。因此,RTTI对于以这种方式防止粉碎攻击是完全没用的。
随意提出RTTI的任何其他有效用例,因为我完全不相信。
编辑:boost::any
被提到了。就boost::any
而言,您可以禁用RTTI并使用以下typeid实现:
typedef const void* typeinfo_nonrtti;
template <typename T> typeinfo_nonrtti typeid_nonrtti();
template <typename T> class typeinfo_nonrtti_helper
{
friend typeinfo_nonrtti typeid_nonrtti<T>();
static char unique;
};
template <typename T> char typeinfo_nonrtti_helper<T>::unique;
template <typename T>
typeinfo_nonrtti typeid_nonrtti() { return &typeinfo_nonrtti_helper<T>::unique; }