我需要将指针转换为Long(sendmessage()),我想安全地检查变量是否正确。所以我正在考虑进行dynamic_cast,但这不适用于非虚拟的类。然后我想到做 typeid ,但这将起作用,直到我传递一个派生 var 作为其基础。

有什么方法可以检查指针在运行时是否是我所期望的?有没有一种方法可以使用 typeid 来查看指针是否是从特定基派生的类型?

有帮助吗?

解决方案

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

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

其他提示

您对SendMessage()的引用让我觉得MS Windows就是您的平台,然后使用指针(Windows)的规则。它详细介绍了Microsoft在此类情况下为您提供的PtrToLongPtrToUlong函数以及其他功能。

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

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

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

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

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

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

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

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

  • 如果您是否可以确定转换为 long 和 back 会产生相同的值,请查看 安全地检查变量的类型
    鉴于另一个应答者链接到的“使用指针的规则”MS-Site,正确的类型转换为 UINT_PTR. 。所以你也是 UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr); 转换为整型,然后执行相反的操作将其再次转换回指针。C++ 标准保证恢复原始值。(请参阅我上面给出的链接以获取我的解释)。顺便说一句,微软网站还说 WPARAM 和 LPARAM 根据平台改变它们的大小。所以你可以只使用该变量 vSendMessage 它。
  • 如果您可以在另一端检查指针(转换为某种指针类型)是否指向某个对象,那么答案是 你不能. 。由于您显然不确定使用哪种指针类型来发送它,因此您无法在接收端检查指针指向的动态类型是什么。如果您知道发送方的指针的类型,则首先不需要进行检查。

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

至于检查某些东西是否属于某个类型,您必须有一个基类来开始。如果你创建了基类<!>“虚拟<!>”的析构函数,那么所有派生类都将有VMT。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top