Se supone que un uso-declaración para ocultar una función virtual heredada?
-
10-10-2019 - |
Pregunta
struct level0
{
virtual void foo() = 0;
};
struct level1 : level0
{
virtual void foo() { cout <<" level1 " << endl; }
};
struct level2 : level1
{
virtual void foo() { cout <<" level2 " << endl; }
};
struct level3 : level2
{
using level1::foo;
};
int main()
{
level1* l1 = new level3;
l1->foo();
level3 l3;
l3.foo();
return 0;
}
el código anterior utilizando gcc da
level2
level1
pero en ICC da
level2
level2
¿Cuál es la correcta o es indefinido por la norma?
Editar: Esto demuestra que hay un error con seguridad, considere la siguiente función principal
int main()
{
level3 l3;
l3.foo(); // This prints level1
level3* pl3 = &l3;
pl3->foo(); // This prints level2
level3& rl3 = l3;
rl3.foo(); // This prints level1
level3& rpl3 = *pl3;
rpl3.foo(); // This prints level2
return 0;
}
Así mismo objeto cuando se usa directamente produce resultados diferentes y cuando se utiliza a través de un puntero de mismo tipo produce resultados diferentes !!!
Solución
Un ejemplo de la sección estándar 10.3p2 deja claro que el uso de declaraciones hacen no sobrecargar las funciones virtuales.
Este es un conocido g ++ bug .
Como habrá notado, cuando se llama a la función miembro a través de una referencia o puntero, en lugar de un caso en el que se conoce el tipo dinámico, el error no sucede.
Otros consejos
introduce using level1::foo;
una función foo
en clase level3
que se refiere a level1::foo
.
En una declaración utilizando utilizado como un miembro-declaración, el nombre-específico anidado fi er nombrará una clase base de la clase de ser de fi nido. Tal usando-declaración introduce el conjunto de declaraciones encontraron por nombre de miembro de búsqueda.
Sin embargo, desde level1::foo
es virtual, supongo que al llamarla debe llamar level2::foo
, por tanto, la CPI debe ser correcta.
No estoy tan seguro, de todos modos.
La manera de conseguir level1 level1 por supuesto sería:
struct level3 : level2
{
virtual void foo() { level1::foo(); }
};
Su "por medio de" directiva parece estar informando al compilador que si usted tiene un foo nivel3 y llamada en él, debe invocar la versión level1, pero no es sobrescribir esto a la tabla v.
gcc se ve mal debido a la inconsistencia, no está seguro acerca de la CPI, porque no sé lo que indica la norma.