2010-11-25 39 views
2

J'ai une question qui me dérange pendant quelques jours.Qu'est-ce qui est spécial au sujet du mécanisme de classe abstraite en C++?

La classe abstraite est un type spécial de classe que nous ne pouvons pas instancier, n'est-ce pas? (Qui est noté/spécifié en donnant un "= 0" à au moins une déclaration de méthode, qui ressemble à une réflexion après coup). Quels sont les avantages supplémentaires que le mécanisme de classe abstraite apporte au C++, qu'une classe de base «normale» ne peut pas atteindre?

Répondre

7

Selon le wikibooks section on abstract classes:

Il est un moyen de forcer un contrat entre le concepteur de la classe et les utilisateurs de cette catégorie. Si nous souhaitons créer une classe concrète (une classe qui peut être instanciée) à partir d'une classe abstraite, nous devons déclarer et définir une fonction membre correspondante pour chaque fonction membre abstraite de la classe de base. Comme mentionné

, il est un moyen de définir une interface à laquelle les classes dérivées doivent se conformer. Leur exemple de la classe abstraite Vehicle est très à propos: vous n'auriez jamais juste un Vehicle dans la vraie vie, vous auriez un Ford Explorer ou une Toyota Prius, mais ceux-ci sont tous les deux conformes (pour l'argument) un ensemble de base de fonctionnalité qui est un Vehicle pourrait définir. Mais, vous ne pouvez pas simplement aller au concessionnaire Vehicle et conduire un Vehicle du lot. Ainsi, vous ne voudrez plus jamais être capable de construire et d'utiliser un objet de base Vehicle où vous voudriez vraiment un objet dérivé spécialisé.

2

Ceci offre le meilleur moyen en C++ de définir une interface sans implémentation par défaut. Le concept C++ n'a pas le concept interface de C#.

+0

Nous pouvons définir une classe de base et choisissez de ne pas fournir d'implémentation pour toute méthode (virtuelle), les classes dérivées, fourniront l'implémentation de la méthode. Nous pouvons instancier cette classe de base sans appeler aucune méthode. La chose supplémentaire qu'une classe abstraite offre est que nous ne pouvons pas instancier la classe elle-même, ai-je raison? – riderchap

+0

@riderchap: c'est une fonctionnalité importante, mais pas la seule. L'instanciation d'une classe de base qui n'a pas de comportement défini est complètement ancienne. Les fonctions virtuelles pures donnent au compilateur la capacité de détecter si vous essayez de faire des choses absurdes. Mais même plus que cela, ils forcent les classes dérivées à implémenter certaines méthodes, donc une classe dérivée implémentée de manière incorrecte ne peut pas tomber accidentellement sur la méthode non implémentée qu'elle a héritée de la classe de base. – suszterpatt

+0

@suszterpatt: La classe dérivée n'est pas obligée de l'implémenter. C'est seulement que quelqu'un dans la hiérarchie doit l'implémenter, alors seulement vous pouvez appeler la méthode. C'est le même effet qu'une classe de base déclarant simplement une fonction virtuelle et ne l'implémentant pas. – riderchap

1

C'est l'équivalent de ce que Java a transformé en "interfaces". Fondamentalement, cela implique que la classe elle-même n'est pas utilisable - vous devez remplacer toutes les méthodes pures.

Un exemple est la classe CView de MFC qui a une méthode OnDraw pure - le CView de base ne fait rien et est donc inutile. Vous devez remplacer OnDraw.

(BTW - il est encore possible de prévoir une mise en œuvre d'une méthode pure et implémentations subclassed peut revenir à elle, mais ils ont encore de fournir leur propre override.)

0

Ils sont utilisés comme base classe dans une conception de hiérarchie de classes.
Les classes abstraites sont utilisées pour définir une interface propre pour toutes les classes dérivées.
Au stade de la conception, les classes abstraites définissent une interface, par spécification et les classes dérivées implémentent la fonctionnalité souhaitée en conséquence.
L'utilisation de classes abstraites au lieu de classes "normales" permet également de séparer les détails d'implémentation de l'interface.
Une classe concrète implémente une interface, mais la classe abstraite la définit. Vous pouvez utiliser une classe concrète comme classe de base dans votre conception, mais les classes abstraites ne sont pas destinées à être utilisées directement dans le code et ne peuvent pas être instanciées. Ils servent de prototype. En utilisant la classe "normal" comme vous le dites, vous devez définir une implémentation pour toutes les méthodes.

0

N'y pense pas au niveau de la classe.Regardez

à la méthode, et penser à ce qu'il devrait faire dans le cas par défaut:

virtual std::string getName() const = 0; 

Quelle serait une mise en œuvre juste pour cette méthode? Il n'y en a pas que je puisse penser. En le marquant «virtuel pur», vous vous assurez que si l'utilisateur obtient une instance d'une classe dérivée de votre interface, cette méthode aura un comportement sensé.

La seule autre façon de le faire serait un corps throw NotImplemented("getName");, mais alors vous découvrirez la question lors de l'exécution, et non pas à la compilation, ce qui est aussi agréable :)