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

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 comme play() , stop() , pause() , record() etc ... Ensuite, j'ai des classes Workhorse 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 les utiliser. Je suis un peu méfiant et je ne sais pas vraiment quels sont les avantages / inconvénients, mais ils semblent (selon 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 workhorse 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 nommage 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 de la question.

0
ajouté édité
Vues: 2

9 Réponses

Je serais un peu réticent à utiliser des classes imbriquées ici. Que se passerait-il si vous créiez une classe de base abstraite pour un «pilote multimédia» afin de gérer le contenu principal (workhorse) et une classe distincte pour le travail frontal? La classe frontale peut prendre un pointeur / une référence à 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 workhorse.

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

Je voudrais référencer quelque chose comme un QTextDocument dans Qt. Vous fournissez une interface directe à la gestion de données bare metal, mais passez l'autorité à un objet comme un QTextEdit pour effectuer la manipulation.

0
ajouté

sounds like a case where you could use the strategy pattern

0
ajouté

Une façon de décider d'utiliser ou non des classes imbriquées est de se demander si cette classe joue ou non un rôle de support.

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

0
ajouté

Eh bien, si vous utilisez des pointeurs vers vos classes Workhorse dans votre classe Interface et 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 pour ces chevaux de travail. transmettre 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 au fur et à mesure de la croissance de votre projet. il vous aidera aussi plus tard si vous avez besoin de sous-classer (disons pour différents types de contenu / codec).

Pour plus d'informations sur le modèle PIMPL (section 3.1.1).

0
ajouté

Vous devez utiliser une classe interne uniquement lorsque vous ne pouvez pas l'implémenter en tant que classe distincte à l'aide de l'interface publique de la classe externe en question. Les classes internes augmentent la taille, la complexité et la responsabilité d'une classe, de sorte qu'elles doivent être utilisées avec parcimonie.

Your encoder/decoder class sounds like it better fits the Strategy Pattern

0
ajouté

Vous utiliseriez une classe imbriquée pour créer une classe d'aide (petite) 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 qu'il est plus difficile de les réutiliser. Peut-être souhaitez-vous 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 distincts, que vous pouvez ensuite utiliser dans votre classe VideoPlayer. Le client de VideoPlayer doit maintenant seulement inclure le fichier qui déclare VideoPlayer, et n'a toujours pas besoin de savoir comment vous l'avez implémenté.

0
ajouté

Parfois, il est approprié de masquer les classes d'implémentation de l'utilisateur - dans ce cas, il est préférable de les placer dans un foo_internal.h plutôt que dans la définition de classe publique. De cette façon, les lecteurs de votre foo.h ne verront pas ce que vous préféreriez qu'ils ne soient pas troublés, mais vous pouvez toujours écrire des tests sur chacune des implémentations concrètes de votre interface.

0
ajouté

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 envisagez de compiler votre logiciel sur beaucoup de plates-formes, y compris les anciens compilateurs.

0
ajouté

Une autre chose à garder à l'esprit est de savoir si vous envisagez différentes implémentations 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.

0
ajouté