Pregunta

necesito convertir punteros a largo (SendMessage()) y quiero de forma segura de comprobar si la variable es correcta en el otro lado.Así que estaba pensando en hacer dynamic_cast, pero que no funcionan en las clases que no son virtuales.Entonces pensé en hacer typeid, pero que va a trabajar hasta que me pase un derivado de var como su base.

Hay alguna forma de comprobar si el puntero es lo que yo estoy esperando que durante el tiempo de ejecución?Hay una manera que puedo utilizar typeid a ver si un puntero es un tipo derivado de una base concreta?

¿Fue útil?

Solución

Si todo lo que tienes es un long, entonces no hay mucho que puedas hacer. No hay una forma general de determinar si un número arbitrario representa una dirección de memoria válida. E incluso si sabe que es una dirección de memoria válida, no hay forma de determinar el tipo de cosa a la que apunta el puntero. Si no puede estar seguro del tipo real de la cosa antes de que su dirección se envíe a <=>, entonces no puede estar seguro de que será seguro lanzar el <=> al tipo que planea lanzar a.

Solo tendrá que confiar en que el remitente del mensaje le ha enviado un valor válido. Lo mejor que puede hacer es tomar algunas precauciones para reducir las consecuencias para su propio programa cuando recibe un valor falso.

Otros consejos

Su referencia a SendMessage() hace que me suena como MS Windows es la plataforma y, a continuación, el Reglas para el Uso de Punteros (Windows) se recomienda la lectura.En él se detalla la PtrToLong y PtrToUlong funciones y otras cosas a Microsoft a ofrecer para usted en situaciones como esta.

No puede usar typeid. Se producirá una infracción de acceso si obtiene basura en lugar de un puntero válido, por lo que su cheque no tiene sentido.

Lo que debe hacer es envolver su SendMessage y el código que procesa el mensaje en una única interfaz de tipo seguro. De esta forma, no podrá pasar cosas inesperadas a SendMessage y no necesitará ninguna verificación en el lado receptor.

El sistema de tipo C ++ funciona en tiempo de compilación. Una vez que lanza un puntero a un largo, pierde toda la información de tipo. Un largo es tantos bits en la memoria; no hay forma de identificar que estaba apuntando a un objeto.

PTLib ( http://sourceforge.net/projects/opalvoip/ ) utiliza un PCLASSINFO macro para definir relaciones entre clases. Esto proporciona funciones como IsDescendant y GetClass.

Probablemente podría implementar algo similar.

dynamic_cast funciona comprobando la firma de la tabla de métodos virtuales. Si no tiene métodos virtuales, no tiene VMT, por lo que como dice dynamic_cast no funcionará. Sin embargo, si no tiene VMT, NO tiene absolutamente ningún conocimiento sobre el objeto al que apunta.

Su mejor opción es exigir que los punteros apunten a clases con al menos un método virtual, incluso si es un ficticio. La conversión dinámica funcionará entonces.

No entiendo todavía lo que tu pregunta es acerca de.

  • Si es si o no usted puede estar seguro de que la conversión de una larga y espalda dará el mismo valor, ver Forma segura de comprobar el tipo de una variable
    Teniendo en cuenta las "Reglas para el uso de Punteros" de MS-Sitio de la otra Contestadora vinculado con el tipo correcto para la conversión a es UINT_PTR.Lo que no UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr); para la conversión a un tipo integral, y no a la inversa para lanzar de nuevo al puntero de nuevo.El Estándar de C++ garantiza que el valor original se restaura.(ver el enlace que me dio por encima de mi explicación de que).Que sitio de Microsoft por el camino también se dice que WPARAM y LPARAM cambiar su tamaño dependiendo de la plataforma.Por lo que sólo podría utilizar esa variable v y SendMessage es.
  • Si es que como se puede comprobar en el otro lado si es o no el puntero (convertirse en algún tipo de puntero) puntos a algún objeto, la respuesta es no se puede.Ya que aparentemente no están seguro de qué tipo de puntero se utiliza para enviar, usted no puede comprobar en el lado receptor de lo que el tipo dinámico señala el puntero es.Si usted conoce el tipo del puntero había en el lado del remitente, su cheque no sería necesario en primer lugar.

En Windows, MFC proporciona un método para verificar si un puntero determinado apunta a una ubicación de memoria válida (esto se hace atrapando segfault). No recuerdo el nombre de la función, pero está ahí. Aún así, no garantiza que los contenidos de la memoria señalados sean válidos. Es posible que todavía tenga VMT no válido y bloquee su código. Por supuesto, puede atrapar el segfault usted mismo ( vea MS Knowledge Base )

En cuanto a verificar si algo pertenece a un tipo, debe tener una clase base para comenzar. Si crea el destructor de la clase base & Quot; virtual & Quot ;, todas las clases derivadas tendrán VMT.

Si debe evitar VMT a toda costa, debe tener algún tipo de descriminador que le diga con qué está tratando, como el tipo de evento en los eventos de MS Windows.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top