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 :

Comment dire : "priorité à la classe parente" ?


Sujet :

C++

  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut Comment dire : "priorité à la classe parente" ?
    Hello,

    J'ai une classe qui hérite d'une politique.

    Il me faut une méthode qui manipule des données stockées dans la classe de politique.

    Je voudrais que si la classe de politique implémente cette méthode, ça soit celle-ci qui soit appelée (parce qu'elle sera optimisée), et sinon, qu'il faut appeler une méthode générique de la classe fille.

    Comment faire cela ?

  2. #2
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Citation Envoyé par oodini Voir le message
    sinon, qu'il faut appeler une méthode générique de la classe fille.
    Une méthode générique de la classe fille ? Comment est ce possible ? Si la classe hérite de cette politique, la méthode utilisé ne sera nécessairement pas générique car avec qui d'autre peut elle être utilisée ?

    Pour moi, la méthode générique non optimisée devrait se trouver dans la classe parent. Si ta politique n'a pas de parent, donne lui en un.
    Find me on github

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Le principe de la politique est de spécialiser via une classe parente.
    Ce qui est générique devrait donc se trouver dans la classe fille, il me semble.

  4. #4
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Citation Envoyé par oodini Voir le message
    Le principe de la politique est de spécialiser via une classe parente.
    Dans le cas du CRTP, oui. Une politique n'est pas nécessairement utilisée via CRTP.

    Citation Envoyé par oodini Voir le message
    Ce qui est générique devrait donc se trouver dans la classe fille, il me semble.
    Oui mais uniquement ce qui ne sera pas impacté par le choix de la politique ! Ce qui touche à la politique (puisque tu veux effectuer des opérations sur ses membres) doit être délégué à la politique. Si la politique doit avoir un comportement par défaut et commun à toutes les politiques (quand ce comportement n'est pas surchargé), il doit être dans une classe parente de la politique.
    Find me on github

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Oui mais uniquement ce qui ne sera pas impacté par le choix de la politique ! Ce qui touche à la politique (puisque tu veux effectuer des opérations sur ses membres) doit être délégué à la politique. Si la politique doit avoir un comportement par défaut et commun à toutes les politiques (quand ce comportement n'est pas surchargé), il doit être dans une classe parente de la politique.
    OK. Il faut donc effectivement passer par une classe parente.
    C'est une option que je n'avais pas considérée.

  6. #6
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    [NB: Ce qui suit est un avis personnel]

    Le but des politiques c'est de spécialiser des comportement, si tu définies une politique, il n'y a aucune raison pour que quelqu'un implémente cette politique sans en définir toutes les méthodes du contrat : ca reviendrait à spécifier à moitier un comportement.

    Couplé au SRP, la notion de comportement spécialisé à moitié n'a plus aucun sens. Si un comportement peut-être spécifié à moitié c'est qu'il y a probablement une possibilité de faire un découplage orthogonale de cette politique en deux autres politiques.

  7. #7
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Je suis plutôt d'accord, je n'y avais pas pensé.
    Find me on github

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Le contrat peut dire : "si vous voulez des performances optimales, nous vous encourageons à implémenter cette méthode".

  9. #9
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Tu pourrais poster ton code (enfin juste ce dont on parle) ?

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    En fait, c'est toujours pour mon histoire de matrice avec une implémentation de stockage définie par une classe de politique.

    Toutes les opérations (multiplications, etc), pourraient utiliser une méthode générique faisant appel à operator()(i,j) définie dans la classe de politique, ou éventuellement être également implémentées dans la classe de politique, ce qui éviterait de faire appel au fameux opérateur.

  11. #11
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Tu ne fais pas ca pour éviter seulement l'appel à l'opérateur () ?

  12. #12
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    mes 2 cents sur le sujet precis vu que NT2 gere le meme genre de chose. C'ets pas ta matrice qu'il faut indexer via operator() mais son "storage"

    Si tu decouples conteneur et zone memoire, tes politiques deviennent plus simples

  13. #13
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par oodini Voir le message
    En fait, c'est toujours pour mon histoire de matrice avec une implémentation de stockage définie par une classe de politique.

    Toutes les opérations (multiplications, etc), pourraient utiliser une méthode générique faisant appel à operator()(i,j) définie dans la classe de politique, ou éventuellement être également implémentées dans la classe de politique, ce qui éviterait de faire appel au fameux opérateur.
    Le problème que j'entre aperçois, c'est que tu n'as pas vraiment d'idée bien claire de ce que représente effectivement l'opérateur ()(int, int)

    Il faut te dire que ce n'est, finalement, qu'une fonction comme une autre, et que, en tant que tel, elle fournit un service que tu es en droit d'attendre de la part de ta classe (ici, de la part de ta matrice ) qui correspond, grosso modo, ni plus ni moins qu'à un accesseur du type getValue (int , int), voire, à un couple accesseur / mutateur équivalent (selon la constance de ton opérateur )

    Si tu veux supprimer (ou éviter d'appeler, ce qui, en pratique, revient au même :d) cet opérateur, comment vas tu faire lorsque tu auras besoin du service qu'il fournit

    Tant que les données équivalentes sont accessibles en tant que telles, (par exemple: dans la classe qui en dispose effectivement), il n'y aura "que" le problème que tu finira par te répéter inlassablement (du genre de matrix_data[linge * numcol + col];) ce qui n'est déjà en soit pas vraiment conseillé (du moins en XP, à cause du DRY: don't repeat yourself ).

    Mais, de plus, une fois que tu sors de la classe qui dispose effectivement des données (soit que tu arrives à une classe qui dérive de la première, soit parce que tu veux accéder à une donnée particulière), les solutions envisageables pour permettre cet accès à une donnée particulière ont un gout amère à faire passer!!!

    Tu auras en effet le choix entre:
    • L'amitié, qui peut ne pas être une mauvaise chose, à condition de ne pas en abuser (or, tu auras très certainement besoin en de nombreux endroits d'accéder à une donnée particulière) car définir trop d'amitiés finira par nuire considérablement à ton design, en plus de créer de nombreux couplages forts, ou
    • Modifier l'accessibilité des données, le moins mauvais des cas étant le fait de les faire passer en accessibilité protégée, le pire des cas étant de devoir les faire passer en accessibilité publique
    • Créer un accesseur (et éventuellement un mutateur) qui remplira(rempliront) l'office de l'opérateur, et qui devra(devront) de toutes manières être appelés de gauche ou de droite
    Peut etre y a-t-il des considérations que je n'ai pas prises en compte et qui pourraient contrebalancer mon approche, mais, crois tu vraiment que "le jeu en vaut la chandelle"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  14. #14
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par Joel F Voir le message
    mes 2 cents sur le sujet precis vu que NT2 gere le meme genre de chose. C'ets pas ta matrice qu'il faut indexer via operator() mais son "storage"

    Si tu decouples conteneur et zone memoire, tes politiques deviennent plus simples
    C'est en fait ce que je fais. Mais je me suis très mal expliqué dans mon dernier message.

    Mon operator()(i,j) est effectivement défini dans chaque classe de stockage.

    Mais par exemple, si je prend l'opérateur *=, je peux soit l'implémenter dans la classe de stockage en tapant directement dans mon tableau, soit dans sa classe fille Matrix en faisant appel à l'operator()(i,j).

  15. #15
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par oodini Voir le message
    Mon operator()(i,j) est effectivement défini dans chaque classe de stockage.

    Mais par exemple, si je prend l'opérateur *=, je peux soit l'implémenter dans la classe de stockage en tapant directement dans mon tableau, soit dans sa classe fille Matrix en faisant appel à l'operator()(i,j).
    Idéalement, on pourrait dire que non

    on pourrait ergoter sur le fait que ta classe de stockage n'a pour seule responsabilité que de te permettre de... stocker un certain nombre d'éléments et n'a donc rien d'autre à faire qu'à... permettre d'accéder à ces éléments en lecture / écriture (au travers des opérateurs () constant et non constants par exemple )

    La classe matrice qui utilise ta classe de stockage apporterait, quant à elle, tout ce qui fait que tu peux effectivement l'utiliser comme telle (dont, entre autres, les opérateurs arithmétiques ad-hoc )

    C'est, peut etre, appliquer de manière un peu stricte le principe de la responsabilité unique, mais, si l'idée est de partir sur des politiques, cela pourrait malgré tout s'avérer intéressant

    L'opérateur () deviendrait alors un invariant requis pour l'utilisation d'une classe quelconque comme politique applicable à ta matrice
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #16
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    la matrice recoit des positions "logiques", que la classe de stockage translate en position physique. comme ca le code dans matrix ets trjrs le meme.

  17. #17
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Oui, mais dans le cas de calculs matriciels, on recherche une efficacité maximale. Si on travaille sur une matrice 1000x1000, fournir une implémentation dans une classe de stockage pourrait permettre d'économiser 1 million d'appel à operator()(i,j).

    Pour un bête stockage à plat, cela n'aura sans doute pas d'incidence, car l'implémentation de l'opérateur sera sans doute mis inline. Mais pour d'autres...

  18. #18
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par oodini Voir le message
    Oui, mais dans le cas de calculs matriciels, on recherche une efficacité maximale. Si on travaille sur une matrice 1000x1000, fournir une implémentation dans une classe de stockage pourrait permettre d'économiser 1 million d'appel à operator()(i,j).

    Pour un bête stockage à plat, cela n'aura sans doute pas d'incidence, car l'implémentation de l'opérateur sera sans doute mis inline. Mais pour d'autres...
    Il n'est pas du tout exclu que certains cas particuliers puissent justifier la création de politiques particulières mettant en oeuvre l'une des trois possibilités que j'ai citées dans mon intervention précédente !!!

    Il peut donc tout à fait être justifié de se dire que, finalement, le fait de changer la visibilité des données pour les rendre protégées présentera des avantages (dans le cadre d'une utilisation interne s'entend) indéniables par rapport à l'utilisation massive de l'opérateur ().

    Nous nous mettrons alors dans le cadre d'une spécialisation partielle ou totale de la matrice (qui fournit l'opérateur * ou *= ) en vue d'utiliser la politique de stockage la plus adéquate, cela ne me choquerait absolument pas

    Mais cela n'empêche que cette politique de stockage devrait de toutes manières exposer l'opérateur (), ne serait ce que pour permettre à la matrice de l'exposer elle aussi

    C'est justement là que réside toute la beauté de garder des classes les plus simples possibles, quitte à ergoter sur la granularité de leurs responsabilités :

    Si tu te dis que la (les) classe(s) qui ont la responsabilité du stockage des données ne s'occupe de rien d'autre que de cela, tu gardes beaucoup plus de possibilités d'évolution (en fonction des besoins réels auxquels tu sera confronté) que si tu commences, dés le départ, à la complexifier avec des "sous responsabilités" qui devraient, en réalité, échoir à des classes plus spécialisées

    Car, si tu ne prévois pas l'opérateur de multiplication dans ta classe de stockage, tu gardes, par exemple, l'occasion de t'en servir comme d'un simple "tableau double entrée" dans lequel n'intervient absolument pas la notion de "matrice", alors qu'avoir un tableau double entrée présentant un opérateur de multiplication semblerait pour le moins étrange, surtout s'il prend un autre tableau double entrée en paramètre et qu'il l'utilise sur base de l'arithmétique propre aux matrices
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #19
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par oodini Voir le message
    Oui, mais dans le cas de calculs matriciels, on recherche une efficacité maximale. Si on travaille sur une matrice 1000x1000, fournir une implémentation dans une classe de stockage pourrait permettre d'économiser 1 million d'appel à operator()(i,j).

    Pour un bête stockage à plat, cela n'aura sans doute pas d'incidence, car l'implémentation de l'opérateur sera sans doute mis inline. Mais pour d'autres...
    l'appel tu t'en fout. Deja ton acces; il a interet a etre vectorisé et pipeliné. L'important c'est pas leur nombre c'ets leur impact sur le cache. En travaillant en position logique translté, tu economise un drame enorme des que ton stockage est structuré ou sparse.

  20. #20
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par Joel F Voir le message
    l'appel tu t'en fout. Deja ton acces; il a interet a etre vectorisé et pipeliné. L'important c'est pas leur nombre c'ets leur impact sur le cache. En travaillant en position logique translté, tu economise un drame enorme des que ton stockage est structuré ou sparse.
    Ce que tu dis semble très intéressant. Pourrais-tu développer, STP ?
    A part OpenMP pour la vectorisation, je ne vois pas comment mettre en œuvre ce que tu préconises.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 05/12/2008, 17h41
  2. [cr 8.5] comment exploiter les données d'un "array"
    Par kikidrome dans le forum SAP Crystal Reports
    Réponses: 12
    Dernier message: 09/06/2005, 14h03
  3. Conception d'une classe parente
    Par VincentB dans le forum Langage
    Réponses: 9
    Dernier message: 24/06/2003, 17h28

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