c++ - Dois-je utiliser des classes imbriquées dans ce cas?

Translate

Je travaille sur une collection de classes utilisées pour la lecture et l'enregistrement vidéo. J'ai une classe principale qui agit comme l'interface publique, avec des méthodes commeplay(), stop(), pause(), record()etc ... Ensuite, j'ai des classes de bourreau de travail qui font le décodage vidéo et l'encodage vidéo.

Je viens d'apprendre l'existence de classes imbriquées en C ++, et je suis curieux de savoir ce que les programmeurs pensent de leur utilisation. Je suis un peu méfiant et ne sais pas vraiment quels sont les avantages / inconvénients, mais ils semblent (d'après le livre que je lis) être utilisés dans des cas comme le mien.

Le livre suggère que dans un scénario comme le mien, une bonne solution serait d'imbriquer les classes de bête de somme dans la classe d'interface, donc il n'y a pas de fichiers séparés pour les classes que le client n'est pas censé utiliser, et pour éviter tout conflit de dénomination possible? Je ne connais pas ces justifications. Les classes imbriquées sont un nouveau concept pour moi. Je veux juste voir ce que les programmeurs pensent du problème.

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

Je serais un peu réticent à utiliser des classes imbriquées ici. Et si vous créiez une classe de base abstraite pour un "pilote multimédia" pour gérer les trucs d'arrière-plan (bourreau de travail), et une classe distincte pour le travail frontal? La classe frontale pourrait prendre un pointeur / référence vers une classe de pilote implémentée (pour le type et la situation de support appropriés) et effectuer les opérations abstraites sur la structure de la bête de somme.

Ma philosophie serait d'aller de l'avant et de rendre les deux structures accessibles au client d'une manière raffinée, juste sous l'hypothèse qu'elles seraient utilisées en tandem.

Je ferais référence à quelque chose comme unQTextDocumentdans Qt. Vous fournissez une interface directe à la gestion des données bare metal, mais transmettez l'autorité à un objet tel qu'un QTextEdit pour effectuer la manipulation.

La source
Translate

Vous utiliseriez une classe imbriquée pour créer une (petite) classe d'assistance requise pour implémenter la classe principale. Ou par exemple, pour définir une interface (une classe avec des méthodes abstraites).

Dans ce cas, le principal inconvénient des classes imbriquées est que cela rend plus difficile leur réutilisation. Vous souhaitez peut-être utiliser votre classe VideoDecoder dans un autre projet. Si vous en faites une classe imbriquée de VideoPlayer, vous ne pouvez pas le faire de manière élégante.

Au lieu de cela, placez les autres classes dans des fichiers .h / .cpp séparés, que vous pouvez ensuite utiliser dans votre classe VideoPlayer. Le client de VideoPlayer n'a plus qu'à inclure le fichier qui déclare VideoPlayer, et n'a toujours pas besoin de savoir comment vous l'avez implémenté.

La source
Translate

Une façon de décider d'utiliser ou non des classes imbriquées est de penser si cette classe joue ou non un rôle de soutien ou si elle est propre.

Si elle existe uniquement dans le but d'aider une autre classe, j'en fais généralement une classe imbriquée. Il y a toute une série de mises en garde à cela, dont certaines semblent contradictoires, mais tout se résume à l'expérience et à l'intuition.

La source
Translate

ressemble à un cas où vous pourriez utiliser lemodèle de stratégie

La source
Translate

Parfois, il est approprié de cacher les classes d'implémentation à l'utilisateur - dans ces cas, il vaut mieux les mettre dans un foo_internal.h que dans la définition de classe publique. De cette façon, les lecteurs de votre foo.h ne verront pas ce avec quoi vous préférez ne pas être dérangé, mais vous pouvez toujours écrire des tests contre chacune des implémentations concrètes de votre interface.

La source
Translate

Nous avons rencontré un problème avec un compilateur Sun C ++ semi-ancien et la visibilité des classes imbriquées dont le comportement a changé dans la norme. Ce n'est pas une raison pour ne pas faire votre classe imbriquée, bien sûr, juste quelque chose à savoir si vous prévoyez de compiler votre logiciel sur de nombreuses plates-formes, y compris d'anciens compilateurs.

La source
Translate

Eh bien, si vous utilisez des pointeurs vers vos classes de bêtes de somme dans votre classe Interface et que vous ne les exposez pas en tant que paramètres ou types de retour dans vos méthodes d'interface, vous n'aurez pas besoin d'inclure les définitions de ces chevaux de travail dans votre fichier d'en-tête d'interface (vous les déclarer à la place). De cette façon, les utilisateurs de votre interface n'auront pas besoin de connaître les classes en arrière-plan.

Vous n'avez certainement pas besoin d'imbriquer des classes pour cela. En fait, des fichiers de classe séparés rendront votre code beaucoup plus lisible et plus facile à gérer à mesure que votre projet se développera. cela vous aidera également plus tard si vous avez besoin de sous-classe (par exemple pour différents types de contenu / codec).

Voici plus d'informations sur leModèle PIMPL(section 3.1.1).

La source
Translate

Vous ne devez utiliser une classe interne que lorsque vous ne pouvez pas l'implémenter en tant que classe séparée en utilisant l'interface publique de la classe externe potentielle. Les classes internes augmentent la taille, la complexité et la responsabilité d'une classe, elles doivent donc être utilisées avec parcimonie.

Votre classe d'encodeur / décodeur semble mieux adaptée auModèle de stratégie

La source
Vanessa Lee
Translate

Une raison d'éviter les classes imbriquées est si vous avez l'intention d'encapsuler le code avec swig (http://www.swig.org) pour une utilisation avec d'autres langues. Swig a actuellement des problèmes avec les classes imbriquées, donc l'interfaçage avec des bibliothèques qui exposent des classes imbriquées devient un vrai problème.

La source
Translate

Une autre chose à garder à l'esprit est de savoir si vous envisagez des implémentations différentes de vos fonctions de travail (telles que le décodage et l'encodage). Dans ce cas, vous voudriez certainement une classe de base abstraite avec différentes classes concrètes qui implémentent les fonctions. Il ne serait pas vraiment approprié d'imbriquer une sous-classe distincte pour chaque type d'implémentation.

La source