2011-09-01 5 views
2

dérivé le code suivant Tenir compte:méthode virtuelle provoque une erreur de compilation dans la classe

#include <iostream> 
using namespace std; 

class A 
{ 
public: 
    virtual int f() {cout <<"A:: f()\n"; return 1;} 
    virtual void f(int) {cout <<"A:: f(int)\n";} 
    virtual void g() {cout <<"A::g()\n";} 
}; 

class B3 : public A 
{ 
public: 
    void f() {cout <<"B3::f()\n";} 
}; 

int main() 
{ 
    return 0; 
} 

Elle produit l'erreur suivante:

..\main.cpp:17: error: conflicting return type specified for 'virtual void B3::f()' 
..\main.cpp:9: error: overriding 'virtual int A::f()' 

mais pourquoi? dans le pire des cas, je pense que j'aurais un cas Hiding, mais j'obtenir erreur de compilation concernant virtual int f() {cout <<"A:: f()\n"; return 1;}

remerciements de A, Ronen

Répondre

0

Ne pas confondre avec la clandestinité remplaçant. Vous remplacez les virtuals.

Votre définition de classe est équivalente à:

class B3 : public A 
{ 
public: 
    virtual void f() {cout <<"B3::f()\n";} 
}; 

Une fois qu'une fonction déclarée pour toutes les classes virtuelles, il reste virtuel découlant de votre classe de base, que vous déclarez explicitement virtuel ou non. Vous essayez donc de surcharger une fonction virtuelle et de changer son type de retour, ce qui est illégal en C++. Si la fonction n'était pas virtuelle, vous cacheriez simplement l'implémentation de la classe de base, donc la modification du type de retour est valide. Il n'y aurait pas d'ambiguïté puisque le compilateur saurait d'où appeler la fonction et quel type de retour s'attendre.

Cependant, envisager d'avoir:

A* a; 
.... 
a->f(); 

Que serait un f() retour? a est un pointeur vers A, mais peut pointer vers un objet de type B3. Donc, il retourne un int ou ne retourne rien. Voir l'ambiguïté ici?

Au lieu de cela, aucun polymorphisme impliqué,

A a; 
a.f(); 

sera cal f d'un, même que b3.f appelleraient f de B3. Dans l'ensemble, les fonctions de classe de base écrasantes impliquent de garder le même type de retour. Si vous voulez créer une nouvelle fonction avec un type de retour différent, changez sa signature (soit son nom ou ses paramètres - soit les deux).

De toute façon, vous ne devriez même pas faire cela ... Pourquoi voudriez-vous avoir une fonction avec le même nom et aucun paramètre ne renvoie des choses différentes? L'ajout d'une fonction séparée ne serait-il pas plus lisible?

0

Vous auriez caché si f() aurait eu une liste de paramètres différente, ou non déclaré comme virtuel sur la classe de base. Dans le premier cas, étant donné que la surcharge ne chevauche pas les limites d'héritage, le f de A aurait été caché. Mais ce n'est pas le cas, puisque vous avez f() sur les deux classes, qui ne diffèrent que par la valeur de retour. La covariance des valeurs de retour est la seule différence autorisée, et puisque ce n'est pas le cas (void n'hérite pas de int), vous obtenez l'erreur.

+0

Vous n'avez pas besoin d'une liste de paramètres différente pour masquer les fonctions de base. –

+0

@Luchian, oui, vous pouvez également cacher en utilisant constness différent. Est-ce ce que tu avais en tête? Y a-t-il un autre moyen de cacher une fonction virtuelle? – eran

Questions connexes