Abatido en una jerarquía de diamantes
¿Por qué static_cast
no puede abatirse desde una base virtual ?
struct A {};
struct B : public virtual A {};
struct C : public virtual A {};
struct D : public B, public C {};
int main()
{
D d;
A& a = d;
D* p = static_cast<D*>(&a); //error
}
G++ 4.5 dice:
error: cannot convert from base ‘A’ to derived type ‘D’ via virtual base ‘A’
La solución es usar dynamic_cast
? pero por qué. ¿Qué es lo racional ?
Edit editar {
Muy buenas respuestas a continuación. Sin embargo, no answers detalla exactamente cómo los subobjetos y vtables terminan siendo ordenados. El siguiente artículo da algunos buenos ejemplos para gcc:
http://www.phpcompiler.org/articles/virtualinheritance.html#Downcasting
2 answers
Porque si el objeto era realmente de tipo E
(derivado de D), la ubicación del subobjeto A
en relación con el subobjeto D
podría ser diferente a si el objeto es realmente D
.
En realidad ya sucede si se considera en su lugar la conversión de A a C. Cuando se asigna C, tiene que contener la instancia de A y vive en algún desplazamiento específico. Pero cuando se asigna D, el subobjeto C se refiere a la instancia de A que vino con B, por lo que es desplazamiento es diferente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-18 12:33:57
La respuesta obvia es: porque la norma lo dice. El
la motivación detrás de esto en el estándar es que static_cast
debe estar cerca de trivial-a lo sumo, una simple adición o
resta de una constante al puntero. ¿Dónde está el abatido?
a una base virtual requeriría código más complicado: tal vez
incluso con una entrada adicional en el vtable en algún lugar. (Se
requiere algo más que constantes, ya que la posición de
D
en relación con A
puede cambiar si hay más derivación.)
El conversión es obviamente factible, ya que cuando se llama
una función virtual en un A*
, y la función se implementa
en D
, el compilador debe hacerlo, pero la sobrecarga adicional fue
considerado inapropiado para static_cast
. (Presumiblemente, el
la única razón para usar static_cast
en tales casos es
optimización, ya que dynamic_cast
es normalmente el preferido
solución. Así que cuando static_cast
es probable que sea tan caro como
dynamic_cast
de todos modos, ¿por qué apoyarlo.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-18 12:42:50