使用typeid进行简单的决策

时间:2011-06-22 10:54:16

标签: c++ casting rtti typeid

我的问题涉及在C ++中简单地在运行时捕获转换问题。我知道C ++在大多数情况下都不提供'RTTI'(我只是说我不能改变我的编译器设置并打开它,为了参数的缘故。)。

在我的项目中,我有一个古代图书馆为我提供的容器。我们称之为Frodo和容器Bane。

Frodo的Bane是我必须直接与之互动的容器。它执行得很差,包含了几个相同信息的地图,我必须单独管理。容器包含某种类型的多个实例,称之为Ring。

对于我的实现,我必须使用Ring的子类型OneRing来进行所有其他操作。这是由于我特别实施Frodo's Bane的外部要求。

我有时候必须查看我的列表,让我们说我需要的东西来自OneRing,我无法从任何旧戒指中获取。

有一个机会,只是偶尔的机会,佛罗多将把一个普通的老戒指放入我的Bane。

太过于百事可乐已经意识到C ++无法回答一个简单的问题,比如'这个戒指也是一个OneRing',或者是为了捕捉因为错误戒指而产生的异常,我做了一些谷歌搜索并找到了有像typeid和type_of这样的东西,但有很多理由不使用它们。

因此,将问题限制为简单地想要避免将一个Ring误认为OneRing,是否可以安全有效地完成任务,而无需更改Ring的实现。

感谢大家提出建议!

更新:好下面有很多好的建议,但经过一天的实验,我可以在原生的Visual Studio 2008 C ++中说出关于RTTI的以下内容:

  • C ++只在指针上有RTTI。您无法动态转换void *,如果您要求输入类型信息,它将无效*。 RTTI在指针上。我明白为什么你不“扮演”一个成员(从C ++的疯狂观点来看,在没有成员的语言中你不必做出如此人为的区分),也许这些事实与某些古老的效率/编译器复杂性原因有关。
  • 如果您获得Ring *的类型信息到OneRing,它将是Ring *。为什么他们选择不将信息放在上我不知道。这使得typeid()基本上没用 - 它甚至返回一个私有类,只有一个你可以访问的成员,一个char *名称!这就像11月10日的不友好和无用的规模 - 他们是故意这样做的吗?
  • 可以使用动态强制转换安全地删除继承树,但除非你拥有并知道你收到的任何数据的公共继承祖先,否则你不能这样做。
  • 如果你不属于上述情况,或者由于某种原因你没有RTTI,你就会成为众所周知的小溪,因为除非你实施,否则无法捕捉异常或因错误的施法而产生错误某种形式的RTTI你自己。
  • COM之类的东西试图通过为所有东西提供一个具有预先声明的RTTI信息的公共基础来提供更多有用的RTTI ......我想。 : - )

作为旁注,Microsoft表示(至少自2008年以来) RTTI是C ++的一部分,默认情况下处于启用状态难以置信我发现有多少相互矛盾的信息。

对于那些花费大部分时间在Native Land的人来说,这可能是个老消息,但对我而言,这需要一段时间的试验,一些谷歌搜索,一些在StackOverflow上发布,一些谷歌搜索和一些更多的实验。 / p>

感谢所有指出我正确方向的人,如果你仍然觉得我错过了什么,请纠正我。 : - )

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

  

据我所知,C ++没有提供   在大多数情况下'RTTI'(让我们   只是说我不能改变我的编译器   设置然后打开它   争论的缘故。)。

那是错的。 C ++提供typeid()dynamic_cast,如果您的编译器没有提供它或者您没有打开它,那么那就是您的问题。

  

我做了一些谷歌搜索并发现了   有像typeid和   type_of,但有很多   不使用每一个的原因。

type_of是C ++ / CLI,而不是C ++,但是typeid()是非常好的C ++,任何告诉你不要使用它的人都是白痴,而且就是这样。 20世纪80年代有一些狂热者会告诉你不要将它用于性能或二元膨胀或其他一些可能与30年前有关的废话,但在本世纪写的C ++中,没有任何借口或理由不使用typeid()

您也可以使用dynamic_cast,这正是语言中的内容。