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 !!!

¿Fue útil?

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.

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