IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Itérateurs et héritage


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 47
    Points : 36
    Points
    36
    Par défaut Itérateurs et héritage
    Bonjour à tous,

    Je suis confronté à un problème pour lequel j'avoue être un peu perdu n'étant pas très à l'aise avec le C++ (malheureusement, les habitudes du C sont souvent mauvaises pour le C++).

    Mon problème est le suivant :

    J'ai toute une hiérarchie de classes, donc par exemple :

    A <- B <- C

    C hérite de B qui hérite de A.

    J'aimerais pouvoir implémenter un itérateur dans A. J'aimerais néanmoins que cet itérateur puisse être overridé par B ou C tout comme on peut le faire avec une fonction virtuelle.

    Je voudrais évidemment que le polymorphisme soit respecté. Donc par exemple :

    A var = new B;

    en demandant un itérateur à var, nous aurons l'implémentation effectuée dans B.

    Mes questions sont donc les suivantes :

    - Quelle est la bonne pratique pour l'implémentation des itérateurs ? J'avoue trouver des documentation qui ne donnent jamais une méthode commune, si vous pouviez me fournir une bonne documentation sur le sujet .

    - Comment avoir une hiérarchie "virtuelle" sur de tels itérateurs ?

    Merci beaucoup.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Finance

    Informations forums :
    Inscription : Août 2010
    Messages : 14
    Points : 20
    Points
    20
    Par défaut
    Bonjour,

    en fait tu crées une classe itérateur pour la classe A qui utilisera des méthodes de la classe A donc. Si ces méthodes sont virtuelles et redefinies dans les classes filles tu peux faire un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    A var = new B();
    AIter it = var.getIterator();
    et tu auras un itérateur sur ton instance de B.

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 59
    Points : 120
    Points
    120
    Par défaut
    Salut

    L’intérêt d'un itérateur est d'offrir un moyen générique de parcourir des containers, il en offre une abstraction vis à vis des algorithmes,

    pour cela les itérateurs sont intimement liés au type de container qu'ils parcourent et existent en plusieurs déclinaisons quand c'est possible (forward, randon access ..)

    les containers STL offrent eux mêmes une abstraction par rapport au type de leur contenu, et sont tout le temps des classes finales (pas destinées à être héritées)

    je ne sais pas quel besoin t'amène à vouloir des itérateurs polymorphes, mais je pense que la solution est peut être ailleurs.

    Sinon méfie toi d'un cas d'erreur classique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     A* array = new B[5];
     for(A* elt = array; elt < array+5; ++elt)
     {
    	doSomething(elt);
     }
    Là on traite de façon polymorphe elt qui est un iterateur sur A, alors que array contient des B, (++elt fait des ravages)

    Cdt

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 47
    Points : 36
    Points
    36
    Par défaut
    Merci pour vos réponses.

    @Draker95 : c'est vrai que ça peut être aussi simple que ça. Merci pour l'astuce .

    @kessoufi : en fait j'en ai besoin parce que je développe une librairie de support d'images. J'offre plusieurs possibilités à l'utilisateur d'accès à une image qui ont chacune un compromis facilité/performances très différent.

    Il y a l'accès direct au buffer, le plus performant, mais le moins pratique. Un accès avec des accesseurs très simples à utiliser, mais forcément, selon les types d'images et de buffer, on peut se retrouver avec des calculs assez coûteux pour récupérer directement une valeur au bon endroit du buffer.

    C'est pour ça que j'aimerais une meilleure alternative, l'itérateur, qui me semble le meilleur compromis facilité/performances. J'ai toute une hiérarchie de classes, selon si l'image est planaire ou non-planaire, l'espace colorimétrique, etc.

    Mais toutes ces classes héritent d'une même classe de base "Image". C'est pour cela que j'ai besoin d'un itérateur polymorphique, car je voudrais qu'un itérateur au plus haut niveau d'abstraction itère le buffer correctement.

    J'espère avoir été clair .

    Merci

  5. #5
    Membre à l'essai
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Finance

    Informations forums :
    Inscription : Août 2010
    Messages : 14
    Points : 20
    Points
    20
    Par défaut
    Ce que tu peux faire, je pense, c'est avoir ta hiérarchie de classes :

    A <- B <- C

    et tu fait de même pour les itérateurs :

    iterA <- iterB <- iterC

    de cette façon tu peux redéfinir tes itérateurs sans tout changer.

    Ensuite, tu redefinie la fonction getIterrator sur tes classes qui instancient le bon, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    iterA * B::getIterrator(){
        return new iterB(this);
    }
    Et tu devrais avoir à peu près ce que tu veux.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,

    Sans réflexion plus poussée, la lecture de ton problème me fait penser à te conseiller ces deux lectures : Présentation des classes de Traits et de Politiques en C++ par Alp Mestan
    Acyclic Visitor de Robert C. Martin ou V comme Visiteur de l'excellent blog d'Emmanuel Deloget.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 47
    Points : 36
    Points
    36
    Par défaut
    Bonjour,

    Encore merci pour vos réponses. Finalement j'ai utilisé Boost, et j'ai déclaré dans une classe à part les fonctions que Boost demande d'implémenter comme virtual. Il s'avère que ça fonctionne parfaitement !

    Benjamin

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par benlaug Voir le message
    Bonjour,

    Encore merci pour vos réponses. Finalement j'ai utilisé Boost, et j'ai déclaré dans une classe à part les fonctions que Boost demande d'implémenter comme virtual. Il s'avère que ça fonctionne parfaitement !

    Benjamin
    Boost? Boost.Iterator, je suppose ?

    J'avais proposé l'article sur les traits et politiques car je me suis demandé si la relation d'héritage de tes classes images était bien appropriée. L'espace colorimétrique, le type d'image, le mode de stockage en mémoire, etc relèvent plus d'une politique que d'une relation d'héritage.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 47
    Points : 36
    Points
    36
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Boost? Boost.Iterator, je suppose ?

    J'avais proposé l'article sur les traits et politiques car je me suis demandé si la relation d'héritage de tes classes images était bien appropriée. L'espace colorimétrique, le type d'image, le mode de stockage en mémoire, etc relèvent plus d'une politique que d'une relation d'héritage.
    Merci, malheureusement je lirai cet article quand j'aurais beaucoup plus de temps (malgré le fait que ça m'intéresse). La librairie approche les 10000 lignes de codes, donc une modification structurelle n'est vraiment pas souhaitée, surtout que tout fonctionne parfaitement.

    Après, l'héritage ici a été fait de manière assez simple. Il y a deux templates étant le "cerveau" des opérations. Un pour les images planaires et un pour les non-planaires. L'héritage ne fait que paramétrer ces templates (le codage des éléments dans le buffer (nombres de bits, signé ou non signé, flottant ou non flottant), le nombre de canaux/plans, etc). L'héritage rajoute éventuellement des fonctions propres à un espace colorimétrique (celles-ci se limitent à des accesseurs par canaux, le but étant ici uniquement l'accès au buffer et non les traitements). Vu la hiérarchie effectuée, en cas de bug (en dehors de très rares cas) il suffit d'aller chercher dans les deux templates principaux.

    De plus, je me suis fortement inspiré de IPP pour en arriver à ce résultat.

    Merci encore,

    Benjamin.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Postgresql]Héritage
    Par lheureuxaurelie dans le forum PostgreSQL
    Réponses: 13
    Dernier message: 02/10/2008, 09h18
  2. [Héritage] Vos commentaires....
    Par Fyna dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 03/05/2005, 22h10
  3. [XML Schemas]héritage multiple
    Par nicolas_jf dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 10/06/2003, 12h55
  4. [Postgres] Héritage + Clés
    Par k-reen dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 21/05/2003, 16h37
  5. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo