Al igual que el caso estándar de llamar a una función virtual desde el constructor o destructor de un objeto con funciones virtuales puras también se puede obtener una llamada de función virtual pura (en MSVC al menos) si se llama a un Portal función después de que el objeto ha sido destruido. Obviamente, esto es bastante malo intentarlo, pero si trabajas con clases abstractas como interfaces y te equivocas, entonces es algo que podrías ver. Posiblemente sea más probable si está usando interfaces contadas de referencia y tiene un error de recuento de ref o si tiene una condición de carrera de uso de objeto/destrucción de objeto en un programa de subprocesos múltiples ... Lo que pasa con estos tipos de llamadas puros es que es a menudo es menos fácil comprender lo que está sucediendo, ya que un cheque para los "sospechosos habituales" de llamadas virtuales en Ctor y Dtor saldrá limpio.
Para ayudar a depurar este tipo de problemas, puede, en diversas versiones de MSVC, reemplazar el controlador purecall de la biblioteca en tiempo de ejecución. Para ello, debe proporcionar su propia función con esta firma:
int __cdecl _purecall(void)
y vincularla antes de vincular la biblioteca de tiempo de ejecución. Esto le da a USTED control de lo que ocurre cuando se detecta una llamada pura. Una vez que tenga el control, puede hacer algo más útil que el controlador estándar. Tengo un controlador que puede proporcionar un rastro de pila de donde ocurrió el llamado puro; mira aquí: http://www.lenholgate.com/blog/2006/01/purecall.html para más detalles.
(Tenga en cuenta que también puede llamar a _set_purecall_handler() para instalar su controlador en algunas versiones de MSVC).
¿Alguna razón por la cual el compilador no pudo detectar esto, en general? – Thomas
No veo ninguna razón técnica por la cual el compilador no pudo detectar esto. –
GCC me da una advertencia solamente: test.cpp: En el constructor 'Base :: Base()': test.cpp: 4: advertencia: virtual virtual 'virtual void Base :: doIt()' llamado desde el constructor Pero falla en el momento del enlace. – Thomas