2011-02-04 5 views
1

J'ai une classe de conteneur avec plusieurs itérateurs comme classes imbriquées. La structure est quelque chose ilke ceci:y compris les classes imbriquées

class Grid 
{ 
protected: 
    class Iterator 
    { 
     Iterator(Grid* g) : grid(g){} 
     Grid* grid; 
    } 
    class MoreIterator : public Iterator 
    { 
    } 
} 

Maintenant, je voulais déplacer les itérateurs dans un fichier d'en-tête de leur propre, pour nettoyer le code de conteneurs.

class Grid 
{ 
protected: 
#include "griditerators.h" 
} 

Jusqu'à présent, ceci compile sans erreurs. Mais:

En QtCreator les lignes

Iterator(Grid* g) : grid(g){} 
Grid* grid; 

sont marqués comme des erreurs, en me disant "Grille est pas un nom de type".

Je pensais que je pouvais résoudre ce avec une déclaration en avant dans le fichier griditerator.h:

class Grid; 
class Iterator 
{ 
    Iterator(Grid* g) : grid(g){} 
    Grid* grid; 
} 

Mais cela me donne une erreur de compilation: Class Grille a le même nom que la classe dans laquelle elle est déclarée .

Remplacement de la déclaration avant par #include "grid.h" fonctionne. Mais je pense en quelque sorte que c'est moche.

J'ai donc deux options de travail. L'un montre des erreurs moche dans mon IDE, l'autre je n'aime pas tellement ça.

J'ai essayé d'autres variantes, où l'include n'est pas dans la classe englobante, mais n'a pas pu être compilé pour différentes raisons. Donc ma question est: Y at-il des «meilleures pratiques» ou inclure des modèles pour gérer les classes imbriquées qui sont trop grandes pour les garder dans leur fichier de classe englobant?

Par exemple aurait-il un moyen de déclarer une classe imbriquée comme:

class Grid::Iterator 

Répondre

7

Ne mettez pas la déclaration de classe imbriquée dans un fichier d'en-tête séparé. C'est un mauvais design et cela va embrouiller tout le monde qui doit maintenir votre code. Si la classe imbriquée est trop grande, décomprimez-la et placez-la dans sa propre unité de compilation (combo h/cpp).

+0

Ok, une solution simple :) Je l'ai juste aimé pour les avoir imbriqués, car ils sont très étroitement liés à la classe englobante et tout à fait inutile par leurs propres moyens. Est-il acceptable d'avoir une classe de base (Iterator) et trois classes dérivées (MoreIterator) dans un fichier d'en-tête? –

+0

Bien sûr, je mets régulièrement des dizaines de classes dans un fichier d'en-tête. –

1

Il est facile d'ajouter une implémentation de classe imbriquée dans un fichier séparé. Je le fais tout le temps, mais vous devrez toujours déclarer la classe imbriquée dans son propriétaire. Effectuez les opérations suivantes:

class Grid 
    { 
    protected: 
     class Iterator; 
     class MoreIterator; 
    }; 

Puis dans un vous séparer fichier cpp ou en-tête, vous devrez implémenter vos classes imbriquées de la manière suivante:

class Grid::Iterator 
{ 
    Iterator(Grid* g) : grid(g){} 
    Grid* grid; 
} 
class Grid::MoreIterator : public Iterator 
{ 
} 

La chose cool à ce sujet est que la grille de classe n'a pas Vous devez connaître les détails des deux classes imbriquées, mais les deux classes imbriquées connaissent les détails de la classe Grid et auront les droits d'accès aux données privées dans la classe Grid, comme toute méthode membre de la classe Grid.

+0

Bonne info, mais je pense que la question portait sur les "meilleures pratiques" –