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 :

probleme de gestion des <vector> dans plusieurs classes


Sujet :

C++

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 630
    Points : 30 699
    Points
    30 699
    Par défaut
    Excusez moi, j'étais au boulot, et j'ai été pas mal occupé...

    Je vais quand meme répondre à la question
    Citation Envoyé par Steph_ng
    Je n'ai pas tilté sur le coup, mais si je comprends bien les raisons 1 et 3, j'ai plus de mal pour la deuxième.
    Excepté pour le destructeur qu'il faut déclarer explicitement virtuel, je ne vois pas pourquoi il faudrait absolument écrire les autres à la main s'ils ont le comportement par défaut.
    Le fait est que, typiquement, dés que l'on entre dans une logique d'héritage, on se retrouve avec des objets ayant sémantique d'entité, et non plus avec des objets ayant sémantique de valeur!

    Un objet ayant sémantique de valeur est un objet qui supporte le fait de se retrouver plusieurs fois en mémoire (tels que les types primitifs, les chaines de caractères, voir les points ou les "complexes"), alors que pour un type ayant sémantique d'entité, il ne devrait jamais y avoir plus d'une seule instance de l'objet:

    Koala01 représente une personne (moi-même ) et ne représentera jamais qu'une seule personne ( moi-même )!!! On peut parler de koala01 à des centaines d'endroits, cela n'empêchera pas que l'on ne parlera jamais... que de moi!

    Et tous les services que l'on pourrait demander à koala01, c'est en réalité à moi qu'on les demandera

    On ne pourras ni me copier ni m'affecter (sous la forme d'objet du moins) : au mieux, on pourra faire référence à moi sous la forme d'un pointeur ou d'une référence, et, si c'est sous la forme d'un pointeur, on pourra décider de référencer plutot mikey ou le capitaine crabs

    Une classe personne a donc clairement une sémantique... d'entité.

    Or, on se rend compte que les classes qui font partie d'une hiérarchie d'héritage publique ont, systématiquement, sémantique d'entité!

    C'est la raison pour laquelle il faudra prendre des mesures efficaces en ce qui concerne le constructeur par copie et l'opérateur d'affectation

    Il peut y avoir des cas où l'on aura affaire à des objets ayant sémantique d'entité sans qu'il n'y ait de relation d'héritage public, mais, ce qui est sur, c'est que l'on aura affaire à des objet ayant sémantique d'entité (et ne pouvant donc ni etre affectés ni etre copiés) dés qu'une telle relation existera

    [EDIT]Pour préciser où je veux en venir: avec une relation d'héritage, il va effectivement falloir refuser explicitement le constructeur par copie, que ce soit en le déclarant privé sans le définir (C++03) ou en le déclarant explicitement =delete (c++11) pour éviter de copier les objets ayant sémantique d'entité.

    Il ne faut pas oublier ce Coplien a défini trois types de forme canoniques différentes pour les "big four", et que la forme "naturelle" pour les objets ayant sémantique de valeur est parfaitement prise en charge par le compilateur, dés que les conditions sont remplies (qu'il n'y ait pas d'allocation dynamique à faire, que les membres soient bien copiables et que les objets aient bien sémantique de valeur et, bien sur, qu'il n'y ait pas de déclaration "pouvant passer pour" l'un des big four )... Nous serions bêtes de nous priver de cette facilité [/QUOTE]

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 630
    Points : 30 699
    Points
    30 699
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Pour avoir moult fois fait coder en C++ des gens dont ce n'était pas et dont ça ne sera jamais le métier, je ne suis pas du tout d'accord avec ça, en qui concerne le destructeur (je ne parle pas du reste). Ajouter le destructeur explicitement est trivial et est une bonne habitude à prendre qui rappelle au codeur comment fonctionne le cycle de vie d'un objet, alors que son absence a tendance à lui faire oublier ce mécanisme (notamment pour les développeurs venant du java).
    Oui, mais....

    Je suis d'accord avec toi sur le fait qu'il est important d'apprendre les formes canoniques de coplien, et qu'il est préférable à certains moments de faire implémenter les big four en général, y compris pour les classes ayant sémantique de valeur n'utilisant pas l'allocation dynamique de la mémoire, pour permettre aux gens de se rendre compte du cycle de vie des objets (essnetiellement des objets créés sur la pile d'ailleurs ).

    Mais cela rentre plutot dans le cadre d'une conscientisation sur la portée des variable, sur l'ordre de construction /destruction de celles-ci ou sur les principe de génie logiciel.

    Une fois que "l'élève" a bien compris quand et comment les objets sont créés, copiés, affectés et détruits, il faut rapidement leur faire comprendre que le compilateur est capable de faire les choses tout seul, et qu'il les fera sans erreur (contrairement à une implémentation manuelle qui risque toujours d'en comporter)

  3. #23
    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 159
    Points
    3 159
    Par défaut
    Je suis d'accord, c'est vrai que j'ai présenté ça de manière un peu extrémiste à l'OP.

  4. #24
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Koala01 représente une personne (moi-même ) et ne représentera jamais qu'une seule personne ( moi-même )!!! On peut parler de koala01 à des centaines d'endroits, cela n'empêchera pas que l'on ne parlera jamais... que de moi!

    Et tous les services que l'on pourrait demander à koala01, c'est en réalité à moi qu'on les demandera

    On ne pourras ni me copier ni m'affecter (sous la forme d'objet du moins) : au mieux, on pourra faire référence à moi sous la forme d'un pointeur ou d'une référence, et, si c'est sous la forme d'un pointeur, on pourra décider de référencer plutot mikey ou le capitaine crabs
    Non mais quel égocentrique, celui-là !

    Citation Envoyé par koala01 Voir le message
    Or, on se rend compte que les classes qui font partie d'une hiérarchie d'héritage publique ont, systématiquement, sémantique d'entité!
    Bon, j'ai compris d'où vient le problème.
    Je comprends parfaitement votre raisonnement à tous les deux.
    Ce qui pêche, c'est le point de départ.

    D'un point de vue purement théorique, je ne vois pas pourquoi les classes d'une hiérarchie (à héritage public) ont forcément une sémantique d'entité.
    Cela ne me paraît pas absurde d'avoir deux objets différents (d'une telle hiérarchie) ayant la même valeur, et de les considérer comme « égaux ».
    Cela ne me paraît pas non plus absurde de vouloir copier un tel objet.
    Et si l'on essaie de copier un objet vers un objet d'une classe parente, eh bien tant pis, on tronque.
    Il est vrai que je n'avais pas pensé aux problèmes de cohérence pointés par jblecanard.

    Finalement, je crois que je n'ai pas une vision de suffisante de ce « problème » sur des cas concrets.
    Alors je vais vous faire confiance.
    Si, après mûre réflexion, jamais j'ai l'impression que cela a un sens de vouloir copier des objets polymorphique sur un cas concret, je vous le présenterai, histoire que vous m'expliquiez pourquoi ma conception est foireuse...

    Sinon, j'avais pris l'habitude d'écrire les « big four » quoi qu'il arrive.
    Je crois que je vais me restreindre aux cas où c'est nécessaire.
    Ah, au fait, je peux utiliser l'instruction = default pour tout de même les écrire quoi qu'il arrive (histoire de bien montrer qu'ils sont là), ou c'est une mauvaise idée ?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 630
    Points : 30 699
    Points
    30 699
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Non mais quel égocentrique, celui-là !
    Fallait bien marquer les esprits

    Bon, j'ai compris d'où vient le problème.
    Je comprends parfaitement votre raisonnement à tous les deux.
    Ce qui pêche, c'est le point de départ.

    D'un point de vue purement théorique, je ne vois pas pourquoi les classes d'une hiérarchie (à héritage public) ont forcément une sémantique d'entité.
    Parce que l'héritage publique est une relation EST-UN, au sens sémantique du terme:

    Un client est une personne : tu peux utiliser un client en ne le considérant "que" comme une personne si tu le souhaites, et si tu n'as pas besoin des fonctions propres à son status de client, tout en profitant éventuellement de l'adaptation de certains comportements.

    Cela ne me paraît pas absurde d'avoir deux objets différents (d'une telle hiérarchie) ayant la même valeur, et de les considérer comme « égaux ».
    Ce qui est absurde, c'est d'avoir deux objets différents ayant strictement les mêmes valeurs...

    Mettons que tu aies une hiérarchie de véhicules... Tu auras un grand nombre de voiture, mais, même si tu prend deux voiture de même marque, même modèle, même couleur et mêmes options, tu auras toujours quelque chose de discriminant te permettant de te rendre compte que c'est la voiture de Jean et non celle de Pierre : même en Belgique où les plaques minéralogiques sont rattachées à la personne et non au véhicule, il reste le numéro de chassis.

    Le fait de rouler 1000 km avec la voiture ne va pas faire que, d'un coup, en arrive à créer une autre voiture, alors que, si tu as un point sur un système d'axes , si tu change la valeur de X, tu obtiens bel et bien un autre point!
    Cela ne me paraît pas non plus absurde de vouloir copier un tel objet.
    Et si l'on essaie de copier un objet vers un objet d'une classe parente, eh bien tant pis, on tronque.
    Justement, c'est absurde...

    Imagine que nous fassions cela avec ton compte courent et ton compte d'épargne :

    Tout deux hériteraient naturellement de "compte bancaire".

    Le fait de faire varier leur solde ne crée pas un nouveau compte, et tu ne serais surement pas enchanté de constater que certains mouvements apparaissent sur ton compte parce qu'il a été copié, et qu'il y a donc confusion entre le tien et celui d'un autre (au niveau du numéro)!
    Il est vrai que je n'avais pas pensé aux problèmes de cohérence pointés par jblecanard.

    Finalement, je crois que je n'ai pas une vision de suffisante de ce « problème » sur des cas concrets.
    Alors je vais vous faire confiance.
    Si, après mûre réflexion, jamais j'ai l'impression que cela a un sens de vouloir copier des objets polymorphique sur un cas concret, je vous le présenterai, histoire que vous m'expliquiez pourquoi ma conception est foireuse...
    En attendant, réfléchis déjà aux cas que je viens de donner
    Sinon, j'avais pris l'habitude d'écrire les « big four » quoi qu'il arrive.
    Je crois que je vais me restreindre aux cas où c'est nécessaire.
    Pas plus tard qu'hier, j'ai eu un problème justement avec un opérateur d'affectation au boulot:

    Il a été défini uniquement pour permettre un comptage de référence (car il y avait des fuites mémoires, fut un temps ) et j'ai du modifier la classe pour lui permettre de fournir de nouveaux services...

    C'est une classe qui n'est absolument pas polymorphe, et qui est utilisée sans jamais avoir recours à new ou à delete.

    Conscient de ce fait, je rajoute un membre pour lui permettre de fournir les services supplémentaires que j'en attendais, et, lors des tests, je me suis arrachés les cheveux pendant 8 heures parce qu'il n'y avait rien à faire : mes nouveaux services ne fonctionnaient pas comme il le fallait.

    Je te donnes en mille la raison de ce problème : j'avais veillé à initialier le membre dans les différents constructeurs (y compris dans le constructeur par copie), mais j'avais, simplement... oublié de faire l'affectation du nouveau membre dans l'opérateur d'affectation!!!

    Petite cause, grands effets

    Je ne manques pourtant pas de pratique, mais j'ai quand même oublié de rajouter une petite ligne à l'opérateur d'affectation!

    Peut etre as tu eu la chance de ne jamais avoir le cas, mais, si un jour ca t'arrive, tu risque de changer d'habitude très rapidement
    Ah, au fait, je peux utiliser l'instruction = default pour tout de même les écrire quoi qu'il arrive (histoire de bien montrer qu'ils sont là), ou c'est une mauvaise idée ?
    Ce n'est utilisable qu'en C++2011...

    De plus, je me dis que c'est surtout pour garder le parallèle avec le = delete :p

    A titre personnel, je le ferais sans doute dés le moment où les big four ne doivent pas être publics : pour les rendre protégés pour que seule la classe dérivée puisse les appeler, voir privés avec des amitiés qui vont bien pour que seules certaines classes y aient accès, mais je ne le ferais sans doute pas si leur définition créée par le compilateur me convient : publics et non virtuel (pour le destructeur)

    Maintenant, de là à dire que c'est une mauvaise idée, il y a de la marge

  6. #26
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Citation Envoyé par koala01 Voir le message
    En attendant, réfléchis déjà aux cas que je viens de donner
    Ça reste des cas particuliers.
    Ce n'est pas parce qu'une propriété est vraie sur un élément particulier d'un ensemble qu'elle est vraie sur tous les éléments de cet ensemble.
    Je crois que tu auras du mal à me convaincre complètement.
    Mais comme dit précédemment, je vais faire confiance à votre expérience.

    Citation Envoyé par koala01 Voir le message
    Peut etre as tu eu la chance de ne jamais avoir le cas, mais, si un jour ca t'arrive, tu risque de changer d'habitude très rapidement
    J'ai quand même eu quelques petites erreurs dues à opérateur d'affectation qui n'était plus cohérent avec les constructeurs, mais rien de critique.
    Ceci dit, j'ai pris conscience que c'était prendre un risque inutile...

    Citation Envoyé par koala01 Voir le message
    Ce n'est utilisable qu'en C++2011...
    Nous sommes d'accord...

    Citation Envoyé par koala01 Voir le message
    De plus, je me dis que c'est surtout pour garder le parallèle avec le = delete :p
    C'est ce que je me dis aussi.

    Citation Envoyé par koala01 Voir le message
    A titre personnel, je le ferais sans doute dés le moment où les big four ne doivent pas être publics : pour les rendre protégés pour que seule la classe dérivée puisse les appeler, voir privés avec des amitiés qui vont bien pour que seules certaines classes y aient accès, mais je ne le ferais sans doute pas si leur définition créée par le compilateur me convient : publics et non virtuel (pour le destructeur)
    En fait, lorsque j'avais essayé de faire ça, le compilateur avait râlé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    protected constructor can't be defaulted
    (ou quelque chose dans le genre)
    g++ 4.5.2, je crois.
    Mais il semblerait que, pour les dernières versions, cette limitation disparaisse.

    Citation Envoyé par koala01 Voir le message
    Maintenant, de là à dire que c'est une mauvaise idée, il y a de la marge
    Hum... merci de ta réponse...

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 630
    Points : 30 699
    Points
    30 699
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Ça reste des cas particuliers.
    Ce n'est pas parce qu'une propriété est vraie sur un élément particulier d'un ensemble qu'elle est vraie sur tous les éléments de cet ensemble.
    Je crois que tu auras du mal à me convaincre complètement.
    Mais comme dit précédemment, je vais faire confiance à votre expérience.
    Justement, ce ne sont pas des cas particuliers : ce sont des cas typiques qui tentent de te faire comprendre les enjeux qui se jouent derrière l'héritage public...

    Les classes intervenant dans une hiérarchie d'héritage public ont systématiquement le point commun que, le fait de modifier certaines propriétés (le solde de ton compte courent ou ton adresse) ne provoquera pas une création d'un autre objet et que, d'un autre coté, si certaines propriétés permettant d'identifier un objet donné de manière unique et non ambigüe (l'ensemble nom + prénom + date de naissance, le numéro de compte de ton compte courent, le numéro de châssis d'une voiture,...) sont identiques, c'est que tu as clairement le même objet, et qu'il n'est pas opportun d'en autoriser la copie.

    Il est par contre possible qu'il soit opportun d'en permettre le clônage ( la création d'une copie dont au minimum les propriétés permettant de l'identifier de manière unique et non ambigüe sont différentes).

    Encore une fois, je ne dis pas que tu n'auras pas une sémantique d'entité en dehors de toute hiérarchie d'héritage public, mais une chose est sure : si tu as un héritage public, tu passe fatalement à une sémantique d'entité

  8. #28
    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 koala01 Voir le message
    Ce qui est absurde, c'est d'avoir deux objets différents ayant strictement les mêmes valeurs...

    Mettons que tu aies une hiérarchie de véhicules... Tu auras un grand nombre de voiture, mais, même si tu prend deux voiture de même marque, même modèle, même couleur et mêmes options, tu auras toujours quelque chose de discriminant te permettant de te rendre compte que c'est la voiture de Jean et non celle de Pierre : même en Belgique où les plaques minéralogiques sont rattachées à la personne et non au véhicule, il reste le numéro de chassis.
    Avec des stylos Bic, ça ne marche plus : ils n'ont pas de numéro de chassis.
    Et c'est justement parce qu'il n'y aucun moyen de les discriminer (si ce n'est le réservoir, et encore) que tout un chacun se fait régulièrement piquer son stylo au boulot.

  9. #29
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par oodini Voir le message
    Avec des stylos Bic, ça ne marche plus : ils n'ont pas de numéro de chassis.
    Et c'est justement parce qu'il n'y aucun moyen de les discriminer (si ce n'est le réservoir, et encore) que tout un chacun se fait régulièrement piquer son stylo au boulot.


    Humour à part, la sémantique générale dit "il n'existe pas deux objets identiques au monde". Si tu décris tes deux stylos bic de manière plus précise, alors tu trouveras la différence qui fait que l'un des deux stylos et le tien, et l'autre non. Quitte à aller jusqu'à la description de la structure atomique.

  10. #30
    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 ce qui me concerne mes Bic, je suis toujours victime d'une acquisition de ressource avant que j'ai pu atteindre le destructeur.

  11. #31
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Pour en revenir au problème de cohérence dans les hiérarchies à héritage public, qu'en est-il de swap ?
    Je veux dire, si l'on essaie d'échanger un objet avec un autre objet d'une classe parente.

    Si on laisse la fonction par défaut, qui appelle le constructeur par copie et l'opérateur d'affectation, il n'y a pas de souci vu qu'on a prévu le coup.
    Mais si on est en C++11, ce sont le constructeur par déplacement et l'opérateur d'affectation par déplacement qui sont appelés.
    Faut-il interdire le déplacement d'objets polymorphiques ?

    Et si on eu besoin de redéfinir (ou spécialiser) la fonction swap, comment on est censé prévoir la situation décrite plus haut ?

Discussions similaires

  1. Réponses: 6
    Dernier message: 09/06/2006, 13h17
  2. Probleme de gestion des menus
    Par Orahn dans le forum MFC
    Réponses: 5
    Dernier message: 18/11/2005, 14h07
  3. Probleme de gestion des controls
    Par Ob1 dans le forum Windows
    Réponses: 2
    Dernier message: 16/07/2005, 11h38
  4. Gestion des versions d'objets dans les SGBD
    Par bennus dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 09/05/2005, 13h57
  5. [Oracle]probleme de gestion des utilisateurs
    Par gentarik dans le forum Oracle
    Réponses: 5
    Dernier message: 09/03/2005, 13h58

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