在C ++中,在其他一些不起眼的案例中(主要处理较差的设计选择),RTTI是一种实现所谓的方式 多种方法 。
这种结构(“是”和“as”)对于Delphi开发人员来说非常熟悉,因为事件处理程序通常会将对象转发给共同的祖先。例如,事件OnClick传递唯一的argurment Sender:TObject,无论对象的类型是什么,无论是TButton,TListBox还是其他任何类型。如果您想了解有关此对象的更多信息,则必须通过“as”访问它,但为了避免异常,您可以在之前使用“is”进行检查。这种向下转换允许通过严格的类类型检查无法实现的对象和方法的设计类型绑定。想象一下,如果用户单击Button或ListBox,您想要执行相同的操作,但如果它们为我们提供了不同的函数原型,则无法将它们绑定到相同的过程。
在更一般的情况下,对象可以调用通知对象例如已经改变的函数。但事先它让目的地“亲自”(通过as和is)了解他,但不一定。它通过将self作为所有对象的最常见祖先(Delphi案例中的TObject)来实现这一点
当没有别的办法时。虚拟方法总是首选,但有时它们无法使用。有几个原因导致这种情况发生,但最常见的原因是您没有要使用的类的源代码,或者您无法更改它们。当您使用旧系统或使用闭源商业库时,通常会发生这种情况。
在.NET中,你可能还需要动态加载新的程序集,比如插件,你通常没有基类,但必须使用像duck typing这样的东西。
dynamic_cast<&gt ;,如果我没记错的话,取决于RTTI。当对象通过void指针(无论出于何种原因)时,一些模糊的外部接口也可能依赖于RTTI 那 可能发生)。
话虽这么说,我在10年的专业C ++维护工作中还没有看到typeof()。 (幸运)。
对于运行时类型检查正常的情况,可以参考更有效的C#。
项目3.专门化通用算法 使用运行时类型检查 您可以轻松地重复使用泛型 只需指定新类型参数。 新类型的新实例化 参数表示具有的新类型 类似的功能。 这一切都很棒,因为你写的 更少的代码。但是,有时候是 更通用意味着不采取 一个更具体的优势,但 算法明显优越。 C# 语言规则将此考虑在内。 所需要的只是让你认识到 你的算法可以更多 高效时的类型参数 有更大的能力,然后到 写那个特定的代码。此外, 创建第二个泛型类型 指定不同的约束 并不总是有效。通用 实例化是基于 编译时类型的对象,和 不是运行时类型。如果你没有 考虑到这一点,你可以错过 可能的效率。
项目3.专门化通用算法 使用运行时类型检查
您可以轻松地重复使用泛型 只需指定新类型参数。 新类型的新实例化 参数表示具有的新类型 类似的功能。
这一切都很棒,因为你写的 更少的代码。但是,有时候是 更通用意味着不采取 一个更具体的优势,但 算法明显优越。 C# 语言规则将此考虑在内。 所需要的只是让你认识到 你的算法可以更多 高效时的类型参数 有更大的能力,然后到 写那个特定的代码。此外, 创建第二个泛型类型 指定不同的约束 并不总是有效。通用 实例化是基于 编译时类型的对象,和 不是运行时类型。如果你没有 考虑到这一点,你可以错过 可能的效率。
例如,假设您编写了一个类,该类在通过IEnumerable< T>表示的项目序列上提供反向顺序枚举。为了向后枚举它,您可以迭代它并将项目复制到具有索引器访问权限的中间集合中,例如List< T>然后使用索引器访问向后枚举该集合。但是如果你的原始IEnumerable是IList,为什么不利用它并提供更高效的方式(不复制到中间集合)来向后迭代项目。所以基本上它是一个特殊的我们可以利用但仍然提供相同的行为(迭代序列向后)。
但一般来说,您应该仔细考虑运行时类型检查,并确保它不违反Liskov Substituion Principle。