Question

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 une interface publique, avec des méthodes comme play(), stop(), pause(), record() etc...Ensuite, j'ai des cours de travail qui effectuent le décodage 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 je ne suis pas vraiment sûr des 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 travail dans la classe d'interface, afin qu'il n'y ait pas de fichiers séparés pour les classes que le client n'est pas censé utiliser, et pour éviter tout conflit de nom 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.

Était-ce utile?

La solution

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 » afin de gérer les éléments back-end (bête de travail) et une classe distincte pour le travail front-end ?La classe frontale pourrait prendre un pointeur/référence vers une classe de pilote implémentée (pour le type de média et la situation appropriés) et effectuer les opérations abstraites sur la structure du cheval de bataille.

Ma philosophie serait d'aller de l'avant et de rendre les deux structures accessibles au client de manière soignée, en supposant qu'elles seraient utilisées en tandem.

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

Autres conseils

Vous utiliseriez une classe imbriquée pour créer une (petite) classe d'assistance nécessaire à l'implémentation de 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 aimeriez-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 séparés, que vous pourrez ensuite utiliser dans votre classe VideoPlayer.Le client de VideoPlayer n'a désormais plus qu'à inclure le fichier qui déclare VideoPlayer, et n'a toujours pas besoin de savoir comment vous l'avez implémenté.

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

S'il 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 dépend de l'expérience et de l'intuition.

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

Parfois, il est approprié de cacher les classes d'implémentation à l'utilisateur. Dans ces 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 avec quoi vous préféreriez qu'ils ne soient pas dérangés, mais vous pouvez toujours écrire des tests sur chacune des implémentations concrètes de votre interface.

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 créer votre classe imbriquée, bien sûr, c'est juste quelque chose dont il faut être conscient si vous envisagez de compiler votre logiciel sur de nombreuses plates-formes, y compris d'anciens compilateurs.

Eh bien, si vous utilisez des pointeurs vers vos classes de bête 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 bêtes de somme dans votre fichier d'en-tête d'interface (il vous suffit avant de 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 les 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éveloppe.cela vous aidera également plus tard si vous avez besoin de sous-classer (par exemple pour différents types de contenu/codecs).

Voici plus d'informations sur le Modèle PIMPL (paragraphe 3.1.1).

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 potentielle.Les classes internes augmentent la taille, la complexité et la responsabilité d’une classe et doivent donc être utilisées avec parcimonie.

Votre classe d'encodeur/décodeur semble mieux correspondre à la Modèle de stratégie

Une raison pour éviter les classes imbriquées est si jamais vous avez l'intention d'envelopper le code avec swig (http://www.swig.org) à utiliser avec d’autres langues.Swig a actuellement des problèmes avec les classes imbriquées, donc l'interface avec des bibliothèques qui exposent des classes imbriquées devient vraiment pénible.

Une autre chose à garder à l’esprit est de savoir si vous envisagez déjà 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top