检查X是否通过typeid导出Y.

时间:2008-11-22 20:20:50

标签: c++ casting typeid

我需要将指针转换为long(SendMessage()) 我想安全地检查变量在其他方面是否正确。所以我想做的是dynamic_cast,但是那些不适用于非虚拟的类。然后我想到了做typeid,但这将一直有效,直到我传递一个派生的var作为它的基础。

有没有办法检查指针是否是我在运行时期待的? 有没有办法可以使用typeid来查看指针是否是从特定基类派生的类型?

7 个答案:

答案 0 :(得分:3)

您对SendMessage()的引用让我觉得MS Windows是您的平台,然后推荐阅读Rules for Using Pointers (Windows)。它详细介绍了PtrToLongPtrToUlong函数以及Microsoft在此类情况下为您提供的其他功能。

答案 1 :(得分:1)

如果你拥有的只是long,那么你可以做的并不多。没有通用的方法来确定任意数字是否代表有效的内存地址。即使你知道它是一个有效的内存地址,也无法确定指针指向的东西的类型。如果在将地址强制转换为long之前无法确定事物的真实类型,那么您无法确定将long强制转换为任何类型都是安全的你打算把它投射到。

您只需要相信邮件的发件人已向您发送了有效值。您可以做的最好的事情就是采取一些预防措施,以减少在收到虚假价值时对您自己的程序造成的后果。

答案 2 :(得分:1)

您不能使用typeid。如果你得到垃圾而不是有效的指针,它将导致访问冲突,所以你的检查是荒谬的。

您应该做的是将SendMessage和处理消息的代码包装到单个类型安全的界面中。这样,您将无法将意外的事情传递给SendMessage,并且不需要在接收方进行任何检查。

C ++类型系统在编译时工作。将指针强制转换为long后,将丢失所有类型信息。长期只是记忆中的那么多位;你无法确定它是指向一个物体。

答案 3 :(得分:0)

PTLib(http://sourceforge.net/projects/opalvoip/)使用PCLASSINFO宏来定义类之间的关系。这提供了像IsDescendant和GetClass这样的函数。

你可能会实现类似的东西。

答案 4 :(得分:0)

dynamic_cast通过检查虚方法表的签名来工作。如果您没有虚拟方法,则没有VMT,因此您说dynamic_cast不起作用。但是,如果您没有VMT,则您完全不了解所指向的对象。

最好的办法是要求指针指向至少有一种虚拟方法的类,即使它是虚拟方法。那么动态演员就可以了。

答案 5 :(得分:0)

我还不明白你的问题是什么。

  • 如果您是否可以确定长时间和后退的投射将产生相同的值,请查看Safely checking the type of a variable
    鉴于“使用指针的规则”MS-Site,另一个Answerer链接到,正确的类型转换为UINT_PTR。所以你要UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr);强制转换为整数类型,然后反过来再将其强制转换回指针。 C ++标准保证恢复原始值。 (请参阅我上面给出的链接以解释其中的内容)。顺便说一句,微软网站也说WPARAM和LPARAM根据平台改变了它们的大小。因此,您可以使用该变量vSendMessage
  • 如果你可以在另一方面检查指针(转换为某种指针类型)是否指向某个对象,答案是你不能。由于您显然不确定使用哪种指针类型来发送它,因此您无法在接收端检查指针指向的动态类型。如果您知道指针在发件人方面的类型,那么首先不需要检查。

答案 6 :(得分:0)

在Windows中,MFC提供了一种方法来检查给定指针是否指向有效的内存位置(这是通过捕获segfault来完成的)。我不记得功能名称,但它就在那里。但是,它不能确保指向的内存内容有效。它可能仍然具有无效的VMT并导致代码崩溃。当然,您可以自己陷阱(see MS Knowledge Base

至于检查某些东西是否属于某个类型,您必须有一个基类来开始。如果使基类的析构函数为“virtual”,则所有派生类都将具有VMT。

如果你必须不惜一切代价避免使用VMT,你必须有某种描述符来告诉你你正在处理什么,例如MS Windows事件中的事件类型。