J'ai rencontré ce problème plusieurs fois et je voudrais savoir s'il existe une méthode ou un modèle simple que je peux utiliser pour le résoudre. Imaginez une structure arborescente dans laquelle chaque nœud contient un conteneur STL (vecteur) de pointeurs vers des enfants. Je veux que le code client puisse traverser cette arborescence et parcourir les conteneurs enfants pour accéder aux autres parties.Comment parcourir à travers un conteneur dans une autre classe?
Mon problème est que je veux maintenir l'encapsulation pour mes nœuds tout en permettant aux clients de voir facilement tous les enfants pour ce nœud. Je veux également m'assurer que si un client obtient une référence const au nœud racine dans l'arbre, alors tous les accès aux parties suivantes de l'arbre sont aussi const. Dois-je essayer de créer une classe d'itérateur pour mon type de nœud, avoir une méthode de nœud pour renvoyer des itérateurs vectoriels, ou y a-t-il un modèle plus élégant qui me manque?
Edit: Je tiens à souligner à nouveau que si je vois quelques bonnes idées présentées, j'ai des conteneurs de pointeurs à d'autres nœuds. Renvoyer un vector<node *>::const_iterator
n'empêchera pas les clients d'appeler des méthodes non-const sur le nœud. Il protège seulement les pointeurs eux-mêmes de pointer sur différents objets.
Est-ce que cela fonctionnera aussi si node_list est un vecteur de pointeurs vers des nœuds, et je veux que le client ait seulement des pointeurs vers des nœuds const? –
"Le code sait qu'il s'agit d'un itérateur à accès aléatoire" point intéressant, mais le code sait également qu'il s'agit d'un vecteur: "const_iterator". Cependant, il est beaucoup plus facile d'utiliser 'operator +' sans réfléchir, que d'assigner l'itérateur à 'vector :: const_iterator' au lieu de' node :: const_iterator' sans réfléchir. Je me demande s'il y a un cas pour un adaptateur d'itérateur qui ne fait rien d'autre que «rétrograder» l'itérateur qu'il enveloppe à une catégorie spécifique. Ensuite, vous pouvez retourner 'make_forward_iterator (children_.begin())', ou un tel. –
@Steve: Puisque la catégorie fait partie du type de l'itérateur, vous devriez faire la conversion dans le typedef. Je pense que vous pourriez le faire assez facilement en utilisant une classe 'template forward_iterator_wrapper: private RealIteratorT {};'. Il pourrait y avoir des problèmes. Je n'y ai pas réfléchi en profondeur. –