Question

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;
}

le code ci-dessus en utilisant gcc donne

level2
level1

mais donne icc

 level2
 level2

Laquelle est correcte ou est-il pas défini par la norme?

Edit: Cela prouve qu'il ya un bug sûr, considérer la fonction principale suivante

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;
}

Ainsi, le même objet lorsqu'il est utilisé directement produit des résultats différents et lorsqu'il est utilisé par un pointeur de même type produit des résultats différents !!!

Était-ce utile?

La solution

Un exemple dans la section standard 10.3p2 montre clairement que l'utilisation de déclarations font pas surchargent des fonctions virtuelles.

Ceci est un connu g ++ bogue .

Comme vous l'avez remarqué, lorsque vous appelez la fonction membre via une référence ou pointeur, plutôt que d'un cas où le type de dynamique est connu, le bug ne se produit pas.

Autres conseils

using level1::foo; introduit une fonction de foo en classe level3 qui se réfère à level1::foo.

  

Dans une déclaration à l'aide utilisée en tant que membre-déclaration, la spéci fi nom emboîtés er nomme une classe de base de la classe étant défini. Une telle déclaration introduit à l'aide-l'ensemble des déclarations trouvées par nom de membre recherche.

Cependant, comme level1::foo est virtuel, je suppose que, en l'appelant, vous devez appeler level2::foo, ainsi icc doit être droit.

Je ne suis pas si sûr, en tout cas.

La façon d'obtenir niveau1 niveau1 serait bien sûr:

struct level3 : level2
{
   virtual void foo() { level1::foo(); }
};

Votre « en utilisant » la directive semble informer le compilateur que si vous avez un level3 et appel foo là-dessus, il devrait invoquer la version niveau1, mais il est n'écrasez pas cela à la vtable.

gcc semble erroné en raison de l'incompatibilité, pas sûr parce que je ne icc sais pas ce que la norme indique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top