Desde el estándar de C++ (ISO/IEC 14882: 2003 (E)), §12.5.4, sobre la sobrecarga operator delete
:sobrecarga de operadores borrar en una clase base
Si una eliminación expresión comienza con un unario :: operador, el nombre de la función de desasignación se busca en el alcance global. De lo contrario, si delete-expression se usa para desasignar un objeto de clase cuyo tipo estático tiene un destructor virtual, la función de desasignación es la que encuentra la búsqueda en la definición del destructor virtual del tipo dinámico (12.4). De lo contrario, si delete-expression se usa para desasignar un objeto de clase T o una matriz de los mismos, los tipos estáticos y dinámicos del objeto serán idénticos y el nombre de la función de desasignación se buscará en el alcance de T. Si esta búsqueda falla para encontrar el nombre, el nombre se busca en el alcance global. Si el resultado de la búsqueda es ambiguo o inaccesible, o si la búsqueda selecciona una función de desasignación de ubicación, el programa está mal formado.
§12.5.7 también es interesante:
Dado que las funciones de asignación y desasignación miembro son estáticos no pueden ser virtuales. [Nota: sin embargo, cuando la expresión de conversión de una expresión de eliminación se refiere a un objeto de tipo de clase, porque la función de desasignación realmente llamada se busca en el alcance de la clase que es el tipo dinámico del objeto, si el destructor es virtual, el efecto es el mismo. Por ejemplo,
struct B {
virtual ˜B();
void operator delete(void*, size_t);
};
struct D : B {
void operator delete(void*);
};
void f()
{
B* bp = new D;
delete bp; // uses D::operator delete(void*)
}
Aquí, el almacenamiento para el objeto no es de array de clase D se desasigna por D :: operador delete(), debido a la destructor virtual.]
Después de leer esto, me pregunto ...
- ¿Es esta parte del estándar totalmente compatible con todos los principales compiladores de C++ (MSVC++, GCC)?
- Si es así, ¿cómo lo hicieron? ¿Funcion virtual oculta? Llamada de destructor virtual "especial" RTTI?
- Usando el ejemplo del estándar: ¿puede haber problemas si f() y D :: operator delete() se definen en EXE/DLL/DSO por separado? (Suponiendo que todo está compilado usando el mismo compilador, por supuesto)
§5.3.5.5 también pueden ser relevantes:
En la primera alternativa (eliminar objeto), si el tipo estático de la operand es diferente de su tipo dinámico, el tipo estático debe ser una clase base del tipo dinámico del operando y el tipo estático debe tener un destructor virtual o el comportamiento no está definido. En la segunda alternativa (eliminar matriz) si el tipo dinámico del objeto a eliminar difiere de su tipo estático, el comportamiento no está definido.
Supongo que caminan en la mesa virtual. Como dice el estándar, la clase necesita tener un destructor virtual para funcionar de la manera correcta. Esto también es cierto para la versión no sobrecargada de 'delete'. – Xeo
Intenté responder, pero parece que lo que realmente desea es que alguien investigue el código fuente de GCC y le informe. Creo que puedes hacerlo tú mismo. – littleadv