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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    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 chevronné
    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
    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 éclairé
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    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
    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 éclairé
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    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 chevronné
    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
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    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 éclairé
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    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 éclairé
    Inscrit en
    Septembre 2003
    Messages
    391
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 391
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    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

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