2009-05-19 10 views
4

En quoi l'implémentation d'Iterator en Java est-elle différente de celle en C++?Quelle est la différence entre les itérateurs en Java et C++?

+1

vous devez être plus explicite avec votre question. Quel est exactement votre problème? –

+1

peut-être vous aimez lire celui-ci: http://doc.trolltech.com/qq/qq12-qt4-iterators.html et celui-ci http://doc.trolltech.com/4.5/containers.html#the-iterator -classes –

+0

@litb vient de finir de lire ça !! – yesraaj

Répondre

8

Dans la bibliothèque standard C++ (98) actuelle (en particulier la partie anciennement appelée STL) définit une forme d'itérateurs qui sont très proches des pointeurs C (y compris l'arithmétique). En tant que tels, ils pointent juste quelque part. Pour être utile, vous avez généralement besoin de deux pointeurs pour pouvoir parcourir entre eux. Je comprends que C++ 0x introduit des plages qui agissent plus comme des itérateurs Java.

Java a introduit l'interface Iterator (et ListIterator) dans la version 1.2, prenant largement le relais de la version plus verbeuse Enumerable. Java n'a pas d'arithmétique de pointeur, il n'est donc pas nécessaire de se comporter comme un pointeur. Ils ont une méthode hasNext pour voir s'ils vont à la fin, au lieu de nécessiter deux itérateurs. L'inconvénient est qu'ils sont moins flexibles. Le système requiert des méthodes comme subList plutôt que d'itérer entre deux itérateurs sont des points spécifiques dans la liste contenant. Une différence générale dans le style est que tandis que C++ utilise le "polymorphisme statique" à travers des templates, Java utilise des interfaces et le polymorphisme dynamique commun.

Le concept des itérateurs est de fournir la colle pour permettre la séparation de "l'algorithme" (flux de contrôle vraiment) et du conteneur de données. Les deux approches le font raisonnablement bien. Dans des situations idéales, le code "normal" devrait à peine voir les itérateurs.

+2

Je ne pensais pas qu'il y aurait une bonne réponse à cette question, mais celle-ci en est une. +1 –

+0

La bibliothèque standard "C++ (97)" n'existe pas. La norme C++, décrite dans la norme ISO 14882, est apparue en 1998 et a été mise à jour en 2003. Elle ne définit nulle part comment les itérateurs sont implémentés, mais spécifie bien sûr l'interface qu'ils fournissent. –

+0

Il définit précisément comment le * concept * des itérateurs sont mis en œuvre. Ce qui semble être la question. –

6

C++ ne spécifie pas comment les itérateurs sont implémentés. Il spécifie cependant leur interface et le comportement minimal qu'ils doivent fournir pour fonctionner avec d'autres composants de la bibliothèque standard.

Par exemple, pour les itérateurs d'entrée, la norme spécifie qu'un itérateur doit être déréférencé via l'opérateur *. Il ne précise cependant pas comment cet opérateur doit être mis en œuvre.

+0

C'est tout le problème de la surcharge de l'opérateur. – Malfist

+2

Java ne spécifie pas non plus; Iterator est une interface. Je ne pense pas qu'il existe un moyen réel de répondre à la question autrement que par ceci. –

+1

La bibliothèque C++ (la partie anciennement appelée STL) est très précise quant à la définition du concept d'itérateur. –

0

Les implémentations sont définies entièrement par les fournisseurs de bibliothèques/fournisseurs JRE standard en C++/Java respectivement. Ils sont libres de les mettre en œuvre comme ils le souhaitent, tant que leur comportement est conforme aux normes respectives.

+0

C'est vraiment une application différente du mot implémenté. –

1

Les itérateurs C++ (STL) essaient d'imiter autant que possible la syntaxe du pointeur, via une surcharge de l'opérateur.

La spécification standard définit les différents concepts de l'itérateur (par exemple, accès direct, bidirectionnel, accès aléatoire, entrée, sortie). Chaque concept doit correspondre à une interface spécifique (par exemple, l'opérateur ++ pour l'itérateur avant pour passer à l'élément suivant dans l'ordre, - pour bidirectionnel, +, + = pour l'accès aléatoire, etc.).

2

En C++, vous voyez des personnes circuler autour des itérateurs tout le temps. Les itérateurs C++ "pointent" vers un élément spécifique d'un conteneur. Vous pouvez déréférencer un itérateur pour obtenir l'élément (et vous pouvez le faire encore et encore). Vous pouvez effacer l'élément auquel un itérateur fait référence de manière efficace. Vous pouvez également faire des copies d'un itérateur (soit en assignant à une autre variable, soit en passant un itérateur par valeur à une fonction) pour garder une trace de plusieurs endroits en même temps. Les itérateurs en C++ peuvent être "invalidés" par certaines opérations sur le conteneur, en fonction du conteneur. Lorsqu'un itérateur devient invalidé (les règles peuvent être complexes), les opérations avec l'itérateur ont un comportement indéfini et peuvent (de façon incohérente) planter votre programme ou retourner des résultats incorrects; bien que dans certaines structures de données (par exemple std::list), les itérateurs restent valides à travers la plupart des modifications du conteneur.

En Java, vous ne voyez pas ce type d'utilisation. Un itérateur dans Java pointe "entre" deux éléments, plutôt que "à" un élément.La seule façon d'obtenir des éléments avec un itérateur est de le déplacer vers l'avant pour obtenir l'élément que vous avez déplacé. Bien sûr, cela change l'état de l'itérateur, et vous ne pouvez pas revenir en arrière; sauf si vous avez un ListIterator auquel cas vous pouvez vous déplacer à la fois vers l'avant et vers l'arrière (mais il est toujours ennuyeux de devoir avancer et reculer juste pour rester immobile). Vous ne pouvez pas copier un itérateur, car l'interface n'expose pas une méthode de copie publique. par exemple, vous ne pouvez pas simplement passer un marqueur d'un emplacement spécifique à une fonction, sans donner à cette fonction une référence au même itérateur que vous avez, et ainsi leur permettre de changer l'état de votre itérateur. En Java, un itérateur sera invalidé (au moins dans les conteneurs standard) par toute modification du conteneur sauf par les méthodes add() ou remove() de l'itérateur, ce qui est trop conservateur (par exemple, la plupart des modifications sur un LinkedList ne devraient pas affecter un itérateur). Lorsque vous essayez d'utiliser un itérateur invalidé, il soulève ConcurrentModificationException (nommé de manière confuse parce qu'il n'a rien à voir avec Concurrency) au lieu de provoquer un comportement indéfini, ce qui est bien.

Questions connexes