为什么RTTI是必需的?
RTTI,运行时类型信息,为C++引入了一种[温和]反射形式。
它允许知道例如超类的类型,因此允许处理从相同基类型派生的对象的异类集合。以特定于各个超级班的方式。 (假设您有一组“车辆”对象,需要对在阵列中找到的“卡车”对象进行不同的处理)。
RTTI是否需要是一个开放的问题。故事情况表明,Bjarne Stroustrup有意将该功能从原始的C++规范中排除,因为担心它会被滥用。
确实有机会过度使用/滥用反射功能,而当C++最初被引入时,这可能更是一个因素,因为在主流程序员社区中没有这样的OOP文化。这就是说,有了更多的面向对象的精明社区,有效地演示了反射可以做的所有好事(例如用诸如Java或C#等语言)以及现今使用的花哨设计模式,我坚信RTTI即使有时误用,反射特征也非常重要。
我可以想到一个恰当的使用RTTI的情况,它甚至不能工作。
C兼容API执行回调以提供用户定义的void *来将状态结构传递回调用方是相当普遍的。当从C++调用这样一个API时,通过void *参数传递这个指针是很常见的。从回调中,可能需要在传入的指针上调用虚函数。
在某些情况下,如果回调参数不安全(例如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; }
就像我上面所说的,'boost :: any'。 :) – GManNickG 2010-04-16 05:28:41
对于我来说看起来不像RTTI,看起来它会使用在持有者
不好意思,'boost :: any'使用'typeid(ValueType)',而不是'typeid(value)'。因此,即使类型是多态的,它也是纯粹的编译时类型信息。完全没用,你可以在没有'typeid'或使用RTTI的情况下获得相同的效果。 – 2010-04-16 05:54:58
+1,仅用于补偿downvote。不要对新手有意思。 – pyon 2010-04-16 03:32:16
闻起来像功课。 – x0n 2010-04-16 03:37:48
不要“赔偿”downvotes,要么。如果您认为这是一个好问题,请Upvote - 目前的投票不应该影响这一点。 – EMP 2010-04-16 04:20:34