2013-04-05 7 views
5

J'utilise généralement des fonctions virtuelles pures pour que les méthodes requises par mon code fonctionnent correctement. Par conséquent, je crée des interfaces, puis d'autres utilisateurs implémentent leurs classes dérivées. Les classes dérivées ont uniquement ces fonctions virtuelles comme publiques alors que certaines méthodes supplémentaires devraient être implémentées comme privées car mon code ne les appelle pas. Je ne sais pas si cela peut être considéré comme une bonne pratique de la POO (existe-t-il un modèle de conception?). Quoi qu'il en soit, ma question est: Un utilisateur peut-il surcharger une fonction virtuelle pure?Surcharge de fonction virtuelle pure

à savoir

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
}; 

class Derived: 
public Base 
{ 
private: 
    // methods 
public: 
Derived(); 
virtual ~Derived(); 
virtual void foo(int, double, double); //this doesn't work 
}; 

Une solution pourrait être:

virtual void foo(int,double,double=0)=0; 

dans la classe de base, mais il est très limité. Qu'en pensez-vous?

+1

Les surcharges de fonctionnement représentent une ** API différente **. Une classe de base abstraite représente une ** API cohérente **. Donc non, cela n'a pas de sens. –

+0

Votre exemple ne manque-t-il pas 'class Derived: Base'? – nonsensickle

+0

@nonsensical: à droite, je viens d'éditer. merci – Ale

Répondre

9

Ces 2 fonctions sont différentes. Ce dernier ne remplace pas le premier

virtual void foo(int,double)=0; 
virtual void foo(int, double, double); 

Le second est une nouvelle fonction virtuelle spécifique à la dérivée.

Si vous placez un override à la fin, la compilation se plaindra que vous ne surchargez rien. C'est C++ 11 vérifier cependant.

virtual void foo(int, double, double) override; 

L'utilisateur peut remplacer une fonction virtuelle pure pour confirmer l'utilisation override à la fin de la fonction pour vérifier. Dans votre cas, la deuxième fonction est uniquement accessible à l'aide du pointeur ou du type Dérivé. (bien qu'il ne puisse pas être instancié à moins que la fonction virtuelle pure ne soit correctement substituée et implémentée, jusqu'à ce qu'elle soit une classe abstraite). Par conséquent, s'il n'est pas destiné à être surchargé par des classes dérivées de Derived, le rendre virtuel est un surcoût car de toute façon il ne surdose pas la méthode de base.

+0

J'écrivais justement 'override' quand cette réponse est apparue. Donc, voici au moins le lien: http://msdn.microsoft.com/en-us/library/vstudio/jj678987.aspx – Kupto

+0

@Kupto: pourquoi dans l'exemple, d'abord funcC (double = 0.0) override fonctionne alors que dans le deuxième code ça ne marche pas? – Ale

+0

@Ale Je viens de l'essayer et il semble que le mot clé 'override' dans le premier exemple soit redondant, si on prend en compte les commentaires. – Kupto

4

Vous ne pouvez pas. Supposons que vous ayez un pointeur Base pointant vers un objet Derived

Ayant le pointeur Base, vous n'avez "accès" qu'à l'interface de Base (à moins que vous ne lanciez au pointeur Derived, mais ce n'est pas ce dont vous avez besoin).

+0

oui, c'est un problème. La seule solution est donc de créer une classe abstraite mais pas une interface. N'est-ce pas? – Ale

+0

@Ale - Je ne comprends pas votre point. Quelle est la différence entre 'interface' et' abstract class' en C++? –

+0

[link] (http://stackoverflow.com/questions/15387581/more-methods-in-derived-classes-than-base-class), une classe dérivée pourrait avoir plus de fonctions que la classe abstraite. Au lieu de cela, une interface limite le nombre de méthodes (à mon avis). – Ale

3

une fonction surchargée est simplement une fonction de même nom qu'un autre, mais l'acceptation d'un ensemble de paramètres différents, à savoir qu'il est une fonction différente . Cela n'a rien à voir avec le fait qu'une ou plusieurs fonctions surchargées sont virtuelles ou non.

Dans l'exemple que vous avez présenté, je crois qu'un utilisateur pourrait surcharger la fonction pure-virtual, mais seulement après l'avoir surchargé. Et vous ne pouvez pas accéder directement à la fonction à partir de la classe de base - vous devez transtyper le pointeur de la classe de base sur le pointeur de la classe dérivée.

0

Comme indiqué par d'autres, cela ne fonctionnera tout simplement pas.

Plus discrètement, voici ce qui se passe

Derived d; 
d.foo(5, 10.0); // Works as expected 

Base &b = d; // b is polymorphic 
b.foo(3,10,4); // foo(int, double, double) is not in class Base, hence compile-time resolution fails! 
0

Il est ne surchargez pas que les signatures de fonction sont différentes.Selon la règle de polymorphisme pour remplacer une fonction, les signatures et les types de fonctions doivent être identiques.

Dans ce cas, ces fonctions sont différentes. vide virtuel foo (int, double) = 0; vide virtuel foo (int, double, double); Le fait de ne pas surcharger foo dans la classe de base est-il la solution la plus simple?

0

class Base 
{ 
public: 
Base(); 
virtual ~Base(); 
virtual void foo(int,double)=0; 
virtual void foo(int,double,double)=0; 
}; 
Questions connexes