我需要将指针转换为long(SendMessage()) 我想安全地检查变量在其他方面是否正确。所以我想做的是dynamic_cast,但是那些不适用于非虚拟的类。然后我想到了做typeid,但这将一直有效,直到我传递一个派生的var作为它的基础。
有没有办法检查指针是否是我在运行时期待的? 有没有办法可以使用typeid来查看指针是否是从特定基类派生的类型?
答案 0 :(得分:3)
您对SendMessage()
的引用让我觉得MS Windows是您的平台,然后推荐阅读Rules for Using Pointers (Windows)。它详细介绍了PtrToLong
和PtrToUlong
函数以及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)
我还不明白你的问题是什么。
UINT_PTR
。所以你要UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr);
强制转换为整数类型,然后反过来再将其强制转换回指针。 C ++标准保证恢复原始值。 (请参阅我上面给出的链接以解释其中的内容)。顺便说一句,微软网站也说WPARAM和LPARAM根据平台改变了它们的大小。因此,您可以使用该变量v
和SendMessage
。答案 6 :(得分:0)
在Windows中,MFC提供了一种方法来检查给定指针是否指向有效的内存位置(这是通过捕获segfault来完成的)。我不记得功能名称,但它就在那里。但是,它不能确保指向的内存内容有效。它可能仍然具有无效的VMT并导致代码崩溃。当然,您可以自己陷阱(see MS Knowledge Base)
至于检查某些东西是否属于某个类型,您必须有一个基类来开始。如果使基类的析构函数为“virtual”,则所有派生类都将具有VMT。
如果你必须不惜一切代价避免使用VMT,你必须有某种描述符来告诉你你正在处理什么,例如MS Windows事件中的事件类型。