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 :

C++ : copie d'objet ?


Sujet :

C++

  1. #1
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut C++ : copie d'objet ?
    Bonjour, j'ai besoin d'une petite aide pour être sur que je fasse les choses de la bonne maniere.

    Alors, à la base, j'ai une classe "cA" qui posséde quelques données membres (privées).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class cA
    {
    //...
    private:
    int m1,m2,m3;
    };
    j'ai besoin de créer des classe cB et cC qui partagerons la plus grande partie des methodes de cA, ainsi que toutes les données membre (m1,m2...)
    J'ai donc envie de faire une classe de base cbase, et de faire cA, cB et cC qui derive de cbase. Jusque là, pas de problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class cbase
    {
    public:
    cbase(); // constructeur
    virtual ~cbase(); // destructeur
    void meth1()
    virtual void meth2();
    private:
    int m1,m2,m3;
    };
    et les classes filles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class cA : public cbase
    {
    public:
    cA(); // constructeur
    virtual ~cA(); // destructeur
    void meth2();
    };
     
    class cB : public cbase
    {
    public:
    cB(); // constructeur
    virtual ~cB(); // destructeur
    void meth2();
    void meth4();
    };
     
    class cC : public cbase
    {
    public:
    cC(); // constructeur
    virtual ~cC(); // destructeur
    void meth2();
    };
    bon,
    mais maintenant ce que j'ai besoin c'est de pouvoir "copier" un cA vers un cB (ou un c[A|B|C] vers un c[A|B|C] ) comme toutes les doneés membres sont privée, j'ai pas envie de faire des getter et setter pour chacunes (j'en bien une 10aine)
    voilà ce que je voudrait bien faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cbase* truc;
    truc = new cA;
    //...
    // on va "echanger" truc cA en truc cB...
    cbase * tmp = new cB;
    ???? // <--ici une ligne pour "copier" les données privées de truc dans tmp
    delete truc; // plus besoin de truc.
    truc=tmp; // maintenant truc est un cB
    tmp=NULL;
    bon, alors je sais qu'il existe la notion de contructeur de recopie, c'est exactement ca que je cherche a faire, (oui j'aurai pu le dire tout de suite) mais je ne sais pas comment le mettre en oeuvre dans le cadre de classe dérivé (note:a priori je n'instancierai pas de cbase, que des cA,cB et cC)

    quelqu'un pour me donner un coups de main ?
    Merci.

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mars 2006
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Mars 2006
    Messages : 400
    Points : 562
    Points
    562
    Par défaut
    En ajoutant les fonctions...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class cA : public cbase
    {
    public:
        cA(const cbase&);  // crée un cA à partir d'un cbase
        cA& operator=(const cbase&);
    };
    ... tu peux ensuite faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    cbase* truc = new cA;
    cbase* tmp = new cB(*truc);
    delete truc;
    truc = tmp;
    ou encore :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    cA a;
    cB b(a);
    cC c = b;

  3. #3
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    je vois..
    et, est-ce que j'ai besoin de l'operateur "=" si je n'utilise que des pointeurs ? (c-a-d que je ne fais jamais cC c = b;) ?

    Et d'ailleur comment faudrait-il que je fasse si je veux utiliser l'operateur "=" en utilisant des pointeurs ? (car truc = tmp c'est des cbase*, est-ce qu'il faudrait (*truc)=(*tmp) ?)
    question innutile, juste pour ma culture perso.

    Merci.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Ton code me semble fort mal conçu.
    L'héritage public c'est pas vraiment fait pour partager du code.

  5. #5
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Ton code me semble fort mal conçu.
    Désolé de le dire ainsi, mais ca t'en sais rien, vu que tu ne connais pas les specs.
    J'ai bien entendu simplifié pour que ca ne perturbe pas ceux qui voudrait bien m'aider ou me donner des conseils constructifs.

    mais voici des specs, peut être m'indiquera tu une meilleure implémentation :

    l'objet est un personage de jeu vidéo. actuellement il s'agit d'un chat, il a des methodes, et des attributs (position, est-il en train de sauter ? de tomber ? de faire ceci ou celà... monter à une échelle, sa vitesse, son inertie...)
    l'idée est que l'on puisse transformer ce personnage en un autre (qui possède des comportement differents) comme des dans jeu de style mario où on a mario-abeille (qui peut voler, alors que mario-normal non)

    Donc mon implementation consiste a mettre tout ce qui est commun dans la classe de base (c-a-d quasiment toutes les donnes membres), ainsi qu'une majorité des méthodes et de surcharger certaines dans les classes filles (on appelle celà une "spécialisation" me semble-t-il).
    ma classe de base sera virtuelle pure (pas d'instance)

    et donc pour gerer la "transformation", il suffit de "copier" ces attributs vers une nouvelle instance (un mario-abeille par exemple) qui remplacera le joueur dans le jeu. (l'exemple de mario-abeille n'est qu'un exemple...)

    Voilà, je t'invite a m'expliquer maintenant en quoi mon code est "fort mal conçu" ? et donc a me proposer une implémentation plus intéressante.

    Citation Envoyé par loufoque Voir le message
    L'héritage public c'est pas vraiment fait pour partager du code.
    pour moi (mais je ne suis pas un dieu hein) l'héritage me sert pour :
    - faire du polymorphisme (j'appelle le ->dessiner() sur tous les obj du jeu)
    - partager du code
    voilà.

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mars 2006
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Mars 2006
    Messages : 400
    Points : 562
    Points
    562
    Par défaut
    Citation Envoyé par hpfx Voir le message
    je vois..
    et, est-ce que j'ai besoin de l'operateur "=" si je n'utilise que des pointeurs ? (c-a-d que je ne fais jamais cC c = b;) ?
    Non. Cependant, ce peut être un bon exercice d'utiliser l'opérateur "=".

    Citation Envoyé par hpfx Voir le message
    Et d'ailleur comment faudrait-il que je fasse si je veux utiliser l'operateur "=" en utilisant des pointeurs ? (car truc = tmp c'est des cbase*, est-ce qu'il faudrait (*truc)=(*tmp) ?)
    question innutile, juste pour ma culture perso.
    Oui, il faudrait bien utiliser (*truc)=(*tmp).

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    mais voici des specs, peut être m'indiquera tu une meilleure implémentation
    Moi j'en ai une. Ne pas mélanger le personnage et sa transformation dans une seule classe. Lorsque tu transformes Mario en abeille, ce n'est qu'une partie de Mario (et donc de ses attributs et comportements) qui mute, pas tout. Tu ne crées en aucun cas un nouveau Mario.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    class Mario
    {
    public:
     
        void transform(Transformation* transfo);
     
    private:
     
        Vector position;
        Vector speed;
        ...
        Transformation* transfo;
    };
     
    class Transformation
    {
    public:
     
        virtual void xxx() = 0;
        virtual void yyy() = 0;
    };
     
    class Bee : public Transformation
    {
        void xxx();
        void yyy();
    };
    class Ghost : public Transformation
    {
        void xxx();
        void yyy();
    };
     
    Mario mario;
    mario.transform(new Bee);
    mario.transform(new Ghost);

  8. #8
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    Moi j'en ai une. Ne pas mélanger le personnage et sa transformation dans une seule classe. Lorsque tu transformes Mario en abeille, ce n'est qu'une partie de Mario (et donc de ses attributs et comportements) qui mute, pas tout. Tu ne crées en aucun cas un nouveau Mario.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    class Mario
    {
    public:
     
        void transform(Transformation* transfo);
     
    private:
     
        Vector position;
        Vector speed;
        ...
        Transformation* transfo;
    };
     
    class Transformation
    {
    public:
     
        virtual void xxx() = 0;
        virtual void yyy() = 0;
    };
     
    class Bee : public Transformation
    {
        void xxx();
        void yyy();
    };
    class Ghost : public Transformation
    {
        void xxx();
        void yyy();
    };
     
    Mario mario;
    mario.transform(new Bee);
    mario.transform(new Ghost);
    oui mais là c'est un peu ma faute... j'aurai pas du prendre l'analogie avec mario... c'est parceque dans ce cas, on a le personage "normal" et ses transformation...
    Mais dans mon cas, c'est 3 classes de personages qui ont toute la même valeur (on peut imaginer qu'avant de lancer le jeu, on puisse choisir l'un des 3 types pour determiner quel est le type qui debutera)
    en fait, il n'y a pas un type de "normal", et deux transformations évoluées, non les 3 types ont des adptitudes differentes.
    il n'y donc pas de raison de privilegier l'un par rapport à un autre... (pas de personnage "normal")


    Citation Envoyé par Laurent Gomila Voir le message
    Moi j'en ai une.
    mais sinon, tu trouve mon implementation si naze que ca toi aussi ?
    (avec deux avis negatif dont le tiens, je me poserai plus de question)

  9. #9
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par jeremya Voir le message
    Non. Cependant, ce peut être un bon exercice d'utiliser l'opérateur "=".


    Oui, il faudrait bien utiliser (*truc)=(*tmp).
    Merci pour ces reponses.

    ca va surprendre un peu mais j'ai gardé quelques habitude qui me viennent du C : j'aime pas trop les "passages par ref", je sais c'est ridicule.
    ce qui fait qu'en general je crée mes objets (avec new, pas avec malloc je vous rassure ;P) mais quasiment toujours sous forme de pointeur..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    machin * p = new machin;
    ce qui fait que je n'ai jamais l'occasion de les passer par reference...
    par exemple j'aime bien les stocker dans un vecteur de pointeur plutot que dans un vecteur d'objet...
    voilà pourquoi je n'avais jamais utilisé de constructeur par copie ni défini l'operateur =...

    j'ai pas encore commencé implementation mais j'y vois plus clair maintenant... je me laisse encore quelques jours de reflexion et j'y vais.
    Merci a vous tous et en particulier a toi jeremya.
    je repasserai bien sur si vous avez des suggestions.

  10. #10
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    oui mais là c'est un peu ma faute... j'aurai pas du prendre l'analogie avec mario... c'est parceque dans ce cas, on a le personage "normal" et ses transformation...
    Mais dans mon cas, c'est 3 classes de personages qui ont toute la même valeur (on peut imaginer qu'avant de lancer le jeu, on puisse choisir l'un des 3 types pour determiner quel est le type qui debutera)
    en fait, il n'y a pas un type de "normal", et deux transformations évoluées, non les 3 types ont des adptitudes differentes.
    il n'y donc pas de raison de privilegier l'un par rapport à un autre... (pas de personnage "normal")
    Il y a tout de même une partie commune, sorte de base de personnage, et une qui varie selon le type, non ? A mon avis (qui n'est fonction que des infos limitées dont je dispose) ma solution tient toujours la route.

    mais sinon, tu trouve mon implementation si naze que ca toi aussi ?
    (avec deux avis negatif dont le tiens, je me poserai plus de question)
    Pas naze, mais il y a clairement quelque chose de dérangeant. Sans être forcément celle que j'ai citée, il y a très probablement une solution plus jolie à ton problème

  11. #11
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    @Laurent,
    hum, ok et donc là ou avec mon implementation, il "suffit" de je fasse trois methode draw() pour chacunes de mes filles... comment dois-je faire avec ton implementation ?
    mon impl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class perso {
    virtual void draw()=0;
    };
    class chat : perso {
    void draw(); // le dessin pour le chat
    };
    class robot : perso {
    void draw(); // dessin du robot (bien different du chat, le robot a un bras telescopique par exemple, il ne suffit pas de changer un sprite...)
    };
    class chevalier : perso {
    void draw(); // dessin du chevalier
    };
    au moment d'afficher, j'appel :
    joueur->draw(); et voilà.
    avec ton implementation, si j'ai bien suivis ca donne ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class chat {
    void draw()
      { switch(type)
        {case chat :
           // la partie qui dessine le chat...
         break;
        default:
          transfo->draw(); // pour le robot ou le chevalier
        break;
        }
      }
     
    };
    on peut remplacer le switch par un simple if(transfo) mais bon.
    c'est bien ca ?

    - edit :
    et puis a fure et a mesure qu'il va y avoir des transfo il faudra gerer la transfo precedante.
    exemple : on commence chat... on se transforme en robot (new robot), puis en chevalier (new chevalier et delete de robot) puis en chat (delete chevalier)

    ca m'ennuis de devoir a chaque fois analyser d'où on vient pour savoir si faut faire un delete ou pas...
    - si vient de chat : pas delete
    - si va vers chat : pas de new

    avec mon implementation c'est pas dificile, on fera toujours un new, puis une copie, puis un delete. (sauf la premiere fois, mais ca tombe bien c'est deux truc differents, la "transformation" est une chose, et la naissance/mort en est une autre. pour la transfo, c'est une consequence à un bonus par exemple)

    Ps : je ne cherche pas a dire que la miene est meilleur, je cherche a voir ce qu'il faut que je change dans le fonctionnement dans le cas de la tienne (pour l'instant ce n'est qu'une reflexion, j'ai pas encore fais les changements)
    c'est pour eclà que je pose toutes ces question : pour faire les choses comme il faut. merci.

  12. #12
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Pas du tout, Laurent te suggérait le pattern Stratégie ! Il n'y a pas de switch / case... Si tu veux ça ressemble à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    class Personnage
    {
        // partie différente
        Weapon * weapon;
     
        // Partie commune 
    };
     
    class Weapon
    {
       virtual void draw() = 0;
       virtual void Attack() = 0;
    };
     
    class SabreLaser : public Weapon
    {
       void draw() {}
       void Attack() {}
    };
    Bon c'est sommaire, mais c'est l'idée. Tu trouveras plus d'infos ICI par exemple...


    Bonne continuation,

    Poukill

  13. #13
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    hum, ok et donc là ou avec mon implementation, il "suffit" de je fasse trois methode draw() pour chacunes de mes filles... comment dois-je faire avec ton implementation ?
    Pareil, si chaque type a un comportement différent vis-à-vis du dessin. Sinon, un seul draw dans la classe commune suffit.

    exemple : on commence chat... on se transforme en robot (new robot), puis en chevalier (new chevalier et delete de robot) puis en chat (delete chevalier)

    ca m'ennuis de devoir a chaque fois analyser d'où on vient pour savoir si faut faire un delete ou pas...
    - si vient de chat : pas delete
    - si va vers chat : pas de new
    Hmm ? En quoi le chat provoque un comportement différent ?
    Quelque soit le type (chat, chevalier, ...) on détruit l'instance précédente et on affecte la nouvelle au personnage. C'est un remplacement de la partie spécifique du personnage, je ne comprends pas pourquoi tu parles "d'analyser d'où on vient".

  14. #14
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    C'est un remplacement de la partie spécifique du personnage, je ne comprends pas pourquoi tu parles "d'analyser d'où on vient".
    c'est par rapport à ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Mario mario;
    mario.transform(new Bee);
    mario.transform(new Ghost);
    si tu l'as transformé en Ghost et que tu veux le transformer en mario (non ghost) il faut faire un delete du ghost, mais pas de new pour autant.
    en fait mario = chat
    Bee = robot
    et Ghost = chevalier.

    ou alors j'ai pas compris...

  15. #15
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Je me disais bien que le nom "Transforme" n'était pas très clair

    L'idée est d'abstraire tout ce qui est commun à tous les personnages dans ta classe, puis à lui adjoindre par agrégation les comportements qui eux varient. Par exemple, la classe personnage peut être composée d'un :
    - Mode de déplacement
    - Mode de combat
    - Comportement (peureux, kamikaze...)
    - Mode de gestion des blessures (invincible, normal, fragile...)
    - ...

    Et ensuite, tu composes ton personnage au choix, en kit (d'où l'avantage qu'avec autant de code, tu as plein de combinaisons !), et s'il obtient un bonus de déplacement, tu fais évoluer uniquement la partie déplacement du personnage.

    Et du coup, ce qui est commun à tous les modes (points de vie courants, position ?) reste identique naturellement, sans faire de copie.

    Quant au design initial, même si la remarque de Loufoque est un peu sèche, je suis d'accord avec lui : Ton post initial est assez flou en terme dobjectifs, mais il présente des indices qui rendent ce design suspect :
    - Héritage pour du partage de code, et non pas pour modéliser une relation is-a
    - Vocabulaire de getter/setter qui laisse souvent entendre une mauvaise encapsulation.

  16. #16
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    Il y a tout de même une partie commune, sorte de base de personnage, et une qui varie selon le type, non ? A mon avis (qui n'est fonction que des infos limitées dont je dispose) ma solution tient toujours la route.


    Pas naze, mais il y a clairement quelque chose de dérangeant. Sans être forcément celle que j'ai citée, il y a très probablement une solution plus jolie à ton problème
    Je plussoie

  17. #17
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Et ensuite, tu composes ton personnage au choix, en kit (d'où l'avantage qu'avec autant de code, tu as plein de combinaisons !), et s'il obtient un bonus de déplacement, tu fais évoluer uniquement la partie déplacement du personnage.
    Ok ok je suis d'accord avec vous...
    je precise quand même que je ne fais PAS un RPG, je ne vais pas combiner des caracteristiques.
    Citation Envoyé par JolyLoic Voir le message
    Quant au design initial, même si la remarque de Loufoque est un peu sèche, je suis d'accord avec lui : Ton post initial est assez flou en terme dobjectifs,
    mea culpa
    Citation Envoyé par JolyLoic Voir le message
    mais il présente des indices qui rendent ce design suspect :
    - Héritage pour du partage de code, et non pas pour modéliser une relation is-a
    - Vocabulaire de getter/setter qui laisse souvent entendre une mauvaise encapsulation.
    oui enfin, je me permets de préciser :
    - chat is-a personnage, chevalier is-a personnage, robot is-a personnage. et le code commun est donc "partagé", par consequence.
    - vocabulaire : justement je n'ai PAS fais de getter/setter, donc a priori, pas de problème d'encapsulation.

    Je ne suis pas sur d'avoir tout compris sur la maniere dont vous me proposez de faire, je suis neanmoins interessé, mais j'ai peur de faire un peu une usine a gaz (non, je ne combinerai pas des caracteristiques de combat ou autre... d'ailleur il n'y a pas de combat, il ne s'agit pas d'un jeu de role)
    comment vous dire... pour bien vous decrire le truc : l'analogie avec mario n'est pas parfaite (dans mario, il y a un perso de base dit "normal" et il se transforme en mario-abeille, mario-fantome....)
    L'idée se rapproche un peu d'un spychofox ou d'un fury-of-the-furies, et encore je ne sais plus s'il n'y a pas un perso considéré comme "normal".

    Moi, on pourra demarrarer avec le chat ou bien le robot par exemple.
    Le robot ne possede pas que des aptitudes en plus (c'est pas une extension du chat). c'est vraiment des perso differents, deux perso ne partagent pas d'aptitude.

    Il y a une relation 1-1 entre le perso et ses aptitudes, a partir de là je pensais les coder dedans le personnage, prenons l'exemple le plus criant :
    Le robot possede un bras telescopique qui lui permetra de s'accrocher au plafond, il n'y aura que le robot qui sera capable de faire celà.
    En plus celà va modifier pas mal de comportement...
    par exemple : le test du vide-en-dessous est caduque dans le cas ou le bras est sorti et accroché, donc ce test sera surchargé dans la classe robot pour prendre en compte cette particularité.
    autre exemple, les deplacements horizontaux : test sur toute la longueur du bras vertical pour voir si un bloc empeche le deplacement ou pas... donc je vai surcharger la methode (de la classe de base) qui retourne 0/1 si la place est libre.

    qu'en pensez-vous ? est-ce que ca en vaut la peine ?
    je vois comment je pourrai m'en sortir avec mon implementation initiale, mais je ne sais pas trop comment m'en sortir avec celle que vous me proposez.

  18. #18
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Tu as des variables à factoriser. Tu le sais, tu l'as dit toi-même. Donc au moins à ce niveau, tu as une classe de base avec des caractéristiques communes (la classe personnage).
    Par la suite, tu dois décider du statut à accorder aux spécificités de chaque personnage. Par composition, ça me paraît bien plus propre et extensible que par dérivation, car chaque personnage has-some spécificités.

  19. #19
    Membre actif
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par Matthieu Brucher Voir le message
    Tu as des variables à factoriser. Tu le sais, tu l'as dit toi-même. Donc au moins à ce niveau, tu as une classe de base avec des caractéristiques communes (la classe personnage).
    oui, exactement, ca je comprends, c'est ce que je veux faire : les caracteristique communes dans la classe de base.
    Citation Envoyé par Matthieu Brucher Voir le message
    ...car chaque personnage has-some spécificités.
    oui, une (ou plusieurs) mais ils ne se les partages pas entre eux.

    soit c'est commun à tous (marcher, ne pas passer à travers les blocs...)
    soit c'est tres specifique (bras telescopique...)

  20. #20
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par hpfx Voir le message
    oui, une (ou plusieurs) mais ils ne se les partages pas entre eux.

    soit c'est commun à tous (marcher, ne pas passer à travers les blocs...)
    soit c'est tres specifique (bras telescopique...)
    L'art de la bonne conception, et c'est pas toujours très facile, c'est justement de trouver les abstractions qui vont bien.
    Des spécificités les plus tordues pourraient se trouver bien rangées dans un endroit commun (une classe de base bien trouvée).

    C'est pas évident, mais il faut se creuser la tête. Je plussoie tous mes prédécesseurs (mes mentors je devrais même dire) pour te conseiller de toujours préférer la composition à l'héritage en cas de doute.

Discussions similaires

  1. Probleme copie d'objet dans un tableau
    Par ché dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 13/12/2006, 12h15
  2. [FLASH 8] Copy d'objets
    Par bibile dans le forum Flash
    Réponses: 3
    Dernier message: 13/09/2006, 17h18
  3. Méthode de classe et copie d'objets
    Par Duloup dans le forum Général Python
    Réponses: 5
    Dernier message: 11/04/2005, 16h27
  4. [VB6] Copie d'objet
    Par preverse dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 23/08/2004, 10h04
  5. [VB6] Copie d'objets
    Par austin49 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 19/05/2003, 18h05

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