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 :

Getter sur un pointeur de classe abstraite qui fait crash


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 23
    Points : 19
    Points
    19
    Par défaut Getter sur un pointeur de classe abstraite qui fait crash
    Bonjour,

    Je suis toujours sur mon projet étudiant de casse brique. Je suis confronté depuis quelques jours à un problème.
    Je souhaite diffuser un id dans mes formes pour pouvoir les reconnaître. J'ai quelques classes (raquette, balle, brique,...) qui héritent de forme et que je souhaite pouvoir identifier, pour connaître le contenu de mon pointeur forme * dans le code suivant (il peut aussi bien pointer sur un raquette que sur une balle, etc):

    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
    void balle::collision(const listeforme &liste)
    {
        float x,y;
        forme * pforme;
        for(int i = 0; i<4; i++)
        {
            x= scout[i].getx();
            y= scout[i].gety();
            pforme = liste.selection(x,y);//.selection(x,y);
            if((pforme!=this)&&(pforme!=NULL))
            {
                pforme->collision(this,i);
            }
     
        }
     //Fin de partie
        if(pforme->getIdforme()==1) //si c'est une raquette
        {
    //Traitement
        }
        ...
    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 forme
    {
        public:
            ...
            virtual int getIdforme();
     
        protected:
            int idforme;
            ...
        private:
    };
     
    .
    .
    .
     
    int forme::getIdforme()
    {
        return idforme;
    }
    Or le test suivant provoque le plantage de mon programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(pforme->getIdforme()==1)
    Le compilateur ne m'affiche aucune erreur, j'ai plus l'impression d'accéder à une partie de la mémoire qui ne m'appartient pas bizarrement.

    Si vous avez besoin de plus de détail, n'hésitez pas à me demander des précisions.

    Je vous remercie d'avance pour l'aide que vous pourrez m'apportez.

  2. #2
    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, et bienvenue (si je ne te l'ai pas encore souhaitée)
    Citation Envoyé par Exomus Voir le message
    Bonjour,

    Je suis toujours sur mon projet étudiant de casse brique. Je suis confronté depuis quelques jours à un problème.
    Je souhaite diffuser un id dans mes formes pour pouvoir les reconnaître. J'ai quelques classes (raquette, balle, brique,...) qui héritent de forme
    Houlala... Ca, c'est déjà mal barre...

    Car par définition, une forme ca va certes offrir un certain nombre de services mais... aucun qui ait le moindre rapport avec les services que l'on est en droit d'attendre de la part d'une balle, d'une raquette ou d'une brique ...
    et que je souhaite pouvoir identifier, pour connaître le contenu de mon pointeur forme * dans le code suivant (il peut aussi bien pointer sur un raquette que sur une balle, etc):
    Je vais être simple et direct : TU N'A PAS A CONNAITRE LE CONTENU DE QUOI QUE CE SOIT!!! Si tu places les données de tes classes dans l'accessibilité privée, c'est pour deux bonnes raisons:
    • La première, c'est que, en tant qu'utilisateur d'une classe (en gros : dés que tu as décidé "ok, j'ai créé ma classe, maintenant, je passe à ce qui l'utilise"), tu t'en fous royalement des données qui la composent (ou, du moins, tu devrais t'en foutre), car, tout ce qui t'intéresse (ou du moins, qui devrait t'intéresser), c'est sa capacité à répondre à certaines questions ou à réagir à certains ordres. (*)
    • La deuxième est plus simple encore : tu as mis les données dans l'accessibilité privée pour "garder le contrôle" des modifications qu'elles peuvent subir. Si, d'une manière ou d'une autre, tu permet à "n'importe qui" de voir "à quoi la donnée ressemble", ou pire encore, d'aller choisir lui-même la valeur qu'elle doit représenter (en prenant le risque que cette valeur soit erronée), tu avais sans doute plus simple de directement la placer dans l'accessibilité publique

    (*) C'est une erreur commune chez les débutants: beaucoup d'entre eux considèrent les classes comme des agrégats de données, alors qu'il faut les considérer comme des "fournisseurs de services". Autrement dit, la première question à se poser n'est pas "quelles données me permettront de représenter ce concept", mais bien "quels services vais-je attendre de sa part? à quelles questions devra-t-elle pouvoir répondre, quelles ordres voudrai-je pouvoir lui donner?"

    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
    void balle::collision(const listeforme &liste)
    {
        float x,y;
        forme * pforme;
        for(int i = 0; i<4; i++)
        {
            x= scout[i].getx();
            y= scout[i].gety();
            pforme = liste.selection(x,y);//.selection(x,y);
            if((pforme!=this)&&(pforme!=NULL))
            {
                pforme->collision(this,i);
            }
     
        }
     //Fin de partie
        if(pforme->getIdforme()==1) //si c'est une raquette
        {
    //Traitement
        }
        ...
    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 forme
    {
        public:
            ...
            virtual int getIdforme();
     
        protected:
            int idforme;
            ...
        private:
    };
     
    .
    .
    .
     
    int forme::getIdforme()
    {
        return idforme;
    }
    Or le test suivant provoque le plantage de mon programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(pforme->getIdforme()==1)
    Ca, c'est un coup classique : tu as libéré la mémoire dont l'adresse est représentée par un pointeur, mais tu ne l'as pas remis nullptr.

    Ceci dit, l'idéal serait sans doute de t'assurer que l'élément est supprimé de ta liste

    Et ce n'est, malheureusement, pas au niveau du code que tu présente, mais, cherches au niveau de delete que tu peux faire, l'erreur devrait trainer dans ce coin là (**)
    Le compilateur ne m'affiche aucune erreur, j'ai plus l'impression d'accéder à une partie de la mémoire qui ne m'appartient pas bizarrement.
    C'est surement parce que c'est ce qui se passe effectivement

    (**)C'est la raison pour laquelle nous insistons lourdement sur l'utilisation des pointeurs intelligents (std::unique_ptr serait parfaitement adapté dans ton cas). au lieu de faire delete liste.selection(x,y); tu ferais liste.selection(x,y).reset();.

    Et tu serais sur que, même si tu ne supprime pas l'élément de la liste, la prochaine fois que tu testera s'il est à null ou pas, il le sera bel et bien

    Sans compter tous les autres avantages liés aux "capsules RAII" dont les pointeurs intelligents sont les dignes représentants, bien sur
    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

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Salut,

    si tu as besoin d'un id unique pour identifier une instance, this devrait faire l'affaire.
    Si tu espères selon cet id déduire le type réel de la classe, ce qui est ton cas puisque tu dis 1 = raquette : c'est certainement pas une bonne idée et tes classes sont à priori mal pensées, ou mal rangées.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    Bonjour,

    Je comprends que c'est pas terrible comme solution. J'ai le besoin de connaître le contenu de pforme pour ma raquette, pour effectuer un simple traitement de fin de partie. En effet je souhaite traiter dans cette collision de balle, le cas où la balle n'est plus rattrapable ce qui met fin à la partie. Pour se faire j'ai besoin de récupérer la position de ma raquette au sein de collision. Il est apparu que passer un pointeur de raquette dans ma collision n'avait pas de sens, d'autant plus que par le passage de listeforme, je sais pertinemment que ma raquette est référencée dedans.
    Voici un schéma de ce que je souhaite réalisé :
    Pièce jointe 279207
    Or ce test de fin de partie dépend de la hauteur à laquelle est placée ma raquette (le traitement de la condition en dur n'est pas vraiment envisageable) et dépend de la position de ma raquette (si je suis dans la zone de réception de la raquette il ne peut y avoir fin de partie ce qui est logique, sinon je vérifie la condition de hauteur de ma balle)

    Ce que je comprends un petit peu moins, c'est d'accord mes attributs sont "protected", pour éviter que l'on accède aux attributs de ma classe que ce soit en lecture ou en écriture, mais pour le coup le Getter me paraissait une façon propre de retourner la valeur d'un attribut que j'autorise à être accessible en lecture qui est mon id. Ce dernier qui est commun à toutes mes formes, il était donc logique pour moi de diffuser au travers de l'héritage, cet attribut et la méthode getIdforme().
    Ce qui me parait dommage, c'est de passer ma liste de formes qui contient toutes les informations dont j'ai besoin, et de ne pas me servir de cet atout pour gérer ma fin de partie dans la collision de la balle (car pour moi fin de partie = collision avec la ligne de fin de partie).

    Je vous remercie d'avance pour vos réponses

  5. #5
    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 Exomus Voir le message
    Ce que je comprends un petit peu moins, c'est d'accord mes attributs sont "protected", pour éviter que l'on accède aux attributs de ma classe que ce soit en lecture ou en écriture,
    En théorie, les seules choses que tu devrais avoir dans les accessibilités publique et protégée sont... des fonctions membres. Les données, elles, devraient systématiquement être en accessibilité privée, quitte à fournir des fonctions (protégées) permettant aux classes dérivées de donner des ordres "privilégiées" (mais pas des accesseurs et des mutateurs, ca va de soi)

    Car le but d'une classe, c'est de faire respecter ses invariants par TOUT LE MONDE (y compris les classes dérivées), et, comme chaque classe est a priori seule à pouvoir les faire respecter sans se gourer... il faut bien limiter les risques au mieux
    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

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par koala01 Voir le message
    En théorie, les seules choses que tu devrais avoir dans les accessibilités publique et protégée sont... des fonctions membres. Les données, elles, devraient systématiquement être en accessibilité privée, quitte à fournir des fonctions (protégées) permettant aux classes dérivées de donner des ordres "privilégiées" (mais pas des accesseurs et des mutateurs, ca va de soi)

    Car le but d'une classe, c'est de faire respecter ses invariants par TOUT LE MONDE (y compris les classes dérivées), et, comme chaque classe est a priori seule à pouvoir les faire respecter sans se gourer... il faut bien limiter les risques au mieux

    En passant les attributs de ma classe en privé, mes classes n'hériteront plus de ces attributs non ? Donc par exemple, une brique qui hérite de rectangle n'aurait plus d'attributs p1, p2 qui définissent mon rectangle et donc la forme de ma brique ? Comment donc gérer par la suite la taille de ma brique, si je ne peux pas influencer mes attributs au travers des méthodes de ma brique ?

  7. #7
    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 Exomus Voir le message
    En passant les attributs de ma classe en privé, mes classes n'hériteront plus de ces attributs non ? Donc par exemple, une brique qui hérite de rectangle n'aurait plus d'attributs p1, p2 qui définissent mon rectangle et donc la forme de ma brique ? Comment donc gérer par la suite la taille de ma brique, si je ne peux pas influencer mes attributs au travers des méthodes de ma brique ?
    Bien sur qu'elles hériteront des attributs privés...

    Quand on dérive d'une classe, on prend tout le package!!!

    La seule chose, c'est qu'elles ne peuvent pas aller modifier directement ces attributs, et qu'il faut passer par une fonction membre de la classe de base (protégée si les ordres qu'il faut donner sont d'ordre "privilégié" et que tout le monde ne peut pas décider de les donner n'importe quand)

    Mais, c'est de toutes manières l'idée générale de toute la programmation OO : on cache les attributs à l'utilisateur de la classe en lui fournissant des services qui les manipule, de cette manière, on est sur que l'utilisateur ne pourra pas faire de connerie en essayant de les manipuler lui-même.

    Ce principe s'appelle l'encapsulation. Et, contrairement à ce que l'on croit, ce n'est pas le principe essentiel de la programmation OO, vu qu'il était déjà utilisé en C (entre autres pour la structure FILE est les fonctions associées à l'utilisation des fichiers)
    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

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Bien sur qu'elles hériteront des attributs privés...

    Quand on dérive d'une classe, on prend tout le package!!!

    La seule chose, c'est qu'elles ne peuvent pas aller modifier directement ces attributs, et qu'il faut passer par une fonction membre de la classe de base (protégée si les ordres qu'il faut donner sont d'ordre "privilégié" et que tout le monde ne peut pas décider de les donner n'importe quand)

    Mais, c'est de toutes manières l'idée générale de toute la programmation OO : on cache les attributs à l'utilisateur de la classe en lui fournissant des services qui les manipule, de cette manière, on est sur que l'utilisateur ne pourra pas faire de connerie en essayant de les manipuler lui-même.

    Ce principe s'appelle l'encapsulation. Et, contrairement à ce que l'on croit, ce n'est pas le principe essentiel de la programmation OO, vu qu'il était déjà utilisé en C (entre autres pour la structure FILE est les fonctions associées à l'utilisation des fichiers)
    Désolé ma question a du vous sembler bête. C'est juste que lorsque l'on nous a introduit l'héritage en cours, on nous a dit de passer nos attributs en protected plutôt qu'en private, j'ai dû me fourvoyer en pensant que les attributs privés ne se diffusaient pas dans les classes filles.

  9. #9
    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 Exomus Voir le message
    Désolé ma question a du vous sembler bête. C'est juste que lorsque l'on nous a introduit l'héritage en cours, on nous a dit de passer nos attributs en protected plutôt qu'en private, j'ai dû me fourvoyer en pensant que les attributs privés ne se diffusaient pas dans les classes filles.
    Hé bien, celui qui t'a dit ca a raconté une belle connerie...

    Le problème, c'est qu'on ne sait jamais quelle classe va dériver de celle que l'on est occupée à créer. Ni même si c'est nous même ou quelqu'un d'autre qui va créer cette classe.

    Et même si c'est nous-même qui créons la classe dérivée, on risque de le faire tellement longtemps après la première que l'on aura eu le temps d'oublier la moitié de ses invariants.

    Si bien que, si les attributs sont en protected, on risque encore de voir la classe dérivée modifier les attributs en ne respectant pas les invariants de la classe de base, ce qui finira tôt ou tard par mener à la catastrophe.

    Moralité : les attributs TOUJOURS PRIVES. Et, si on prévoit que les classes dérivées puissent avoir des "droits élargis" (par rapport aux autres classes, qui ne sont pas dérivées) sur ces données, on crée les fonctions "qui vont bien" (et qui veilleront à respecter les invariants) dans l'accessibilité protected.

    De cette manière, on "bétonne" les choses et on évite un maximum des conneries qui pourraient être faites au niveau des classes dérivées (et des autres, bien sur)
    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

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2015
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2015
    Messages : 23
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Hé bien, celui qui t'a dit ca a raconté une belle connerie...

    Le problème, c'est qu'on ne sait jamais quelle classe va dériver de celle que l'on est occupée à créer. Ni même si c'est nous même ou quelqu'un d'autre qui va créer cette classe.

    Et même si c'est nous-même qui créons la classe dérivée, on risque de le faire tellement longtemps après la première que l'on aura eu le temps d'oublier la moitié de ses invariants.

    Si bien que, si les attributs sont en protected, on risque encore de voir la classe dérivée modifier les attributs en ne respectant pas les invariants de la classe de base, ce qui finira tôt ou tard par mener à la catastrophe.

    Moralité : les attributs TOUJOURS PRIVES. Et, si on prévoit que les classes dérivées puissent avoir des "droits élargis" (par rapport aux autres classes, qui ne sont pas dérivées) sur ces données, on crée les fonctions "qui vont bien" (et qui veilleront à respecter les invariants) dans l'accessibilité protected.

    De cette manière, on "bétonne" les choses et on évite un maximum des conneries qui pourraient être faites au niveau des classes dérivées (et des autres, bien sur)
    Merci beaucoup pour ces précisions, qui vont m'aider à appréhender de manière plus rigoureuse mes futurs projets.

  11. #11
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 109
    Points
    6 109
    Par défaut
    Citation Envoyé par Exomus Voir le message
    J'ai quelques classes (raquette, balle, brique,...) qui héritent de forme
    Contrairement à koala01, ça ne me choque pas. Par contre, ta fonction getIdforme() me choque.
    Si tu utilises de l'héritage pour gérer les collisions, il faudrait faire du double dispatch.
    Dans le cas présent, cela donnerait :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    class Balle;
    class Brique;
    class Raquette;
     
    class Forme
    {
    public:
    	void collisionAvec(Forme& forme)       {virtCollisionAvecForme(forme);}
    	void collisionAvec(Balle& balle)       {virtCollisionAvecBalle(balle);}
    	void collisionAvec(Brique& brique)     {virtCollisionAvecBrique(brique);}
    	void collisionAvec(Raquette& raquette) {virtCollisionAvecRaquette(raquette);}
    	// ...
    private:
    	virtual void virtCollisionAvecForme(Forme& forme)          = 0;
    	virtual void virtCollisionAvecBalle(Balle& balle)          = 0;
    	virtual void virtCollisionAvecBrique(Brique& brique)       = 0;
    	virtual void virtCollisionAvecRaquette(Raquette& raquette) = 0;
    	// ...
    };
     
    class Balle : public Forme
    {
    public:
    	// ...
    private:
    	void virtCollisionAvecForme(Forme& forme) override {forme.collisionAvec(*this);}
    	void virtCollisionAvecBalle(Balle& balle) override {
    		// Ne rien faire. (Les balles se traversent.)
    	}
    	void virtCollisionAvecBrique(Brique& brique) override {
    		// Rebondir.
    	}
    	void virtCollisionAvecRaquette(Raquette& raquette) override {
    		// Rebondir.
    	}
    	// ...
    };
     
    class Brique : public Forme
    {
    public:
    	// ...
    private:
    	void virtCollisionAvecForme(Forme& forme) override {forme.collisionAvec(*this);}
    	void virtCollisionAvecBalle(Balle& balle) override {
    		// Disparaître.
    	}
    	void virtCollisionAvecBrique(Brique& brique) override {
    		// Ne rien faire.
    	}
    	void virtCollisionAvecRaquette(Raquette& raquette) override {
    		// Ce n'est pas supposé pouvoir se produire.
    		// Possibilités : ne rien faire ou disparaître.
    	}
    	// ...
    };
     
    class Raquette : public Forme
    {
    public:
    	// ...
    private:
    	void virtCollisionAvecForme(Forme& forme) override {forme.collisionAvec(*this);}
    	void virtCollisionAvecBalle(Balle& balle) override {
    		// Ne rien faire.
    		// C'est Balle::virtCollisionAvecRaquette qui fait le boulot.
    	}
    	void virtCollisionAvecBrique(Brique& brique) override {
    		// Ce n'est pas supposé pouvoir se produire.
    		// Ne rien faire.
    	}
    	void virtCollisionAvecRaquette(Raquette& raquette) override {
    		// Cela pourrait se produire si on implémente le multi-joueurs.
    		// Ne rien faire.
    	}
    	// ...
    };

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Autant avoir raquette, balle et brique qui héritent de Forme pour l'affichage, pourquoi pas. Même si afficher un rectangle et un cercle n'ont pas grand rapport : l'un demande une position et une taille de côté, l'autre une position et un rayon.
    Autant pour le gameplay, elles n'ont rien à voir et ne devraient avoir aucun lien de parenté.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  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
    Citation Envoyé par Pyramidev Voir le message
    (1)Contrairement à koala01, ça ne me choque pas.
    Citation Envoyé par Bousk Voir le message
    (2)Autant avoir raquette, balle et brique qui héritent de Forme pour l'affichage, pourquoi pas. Même si afficher un rectangle et un cercle n'ont pas grand rapport : l'un demande une position et une taille de côté, l'autre une position et un rayon.
    (3)Autant pour le gameplay, elles n'ont rien à voir et ne devraient avoir aucun lien de parenté.
    (1) et (2) Et encore, ce qui importe au niveau de l'affichage, ce n'est pas tant de savoir que tu as affaire à une balle, une brique ou une raquette, que de savoir que tu doit afficher un rectangle ou un cercle de telle ou telle couleur à tel ou tel endroit.

    De plus, l'affichage entre très clairement dans la catégorie des éléments destinés à la vue, alors que les notions de balle, de raquette et de briques sont essentiellement des donnée métiers, c'est à dire destinées à faire partie du modèle.

    Et, rien que pour cela, il vaut déjà la peine de séparer clairement les deux notions, car la vue s'en contre fout de la "nature" de ce qu'elle doit afficher: on va lui demander d'afficher des rectangles et des cercles de différentes couleurs, et point barre.

    A contrario, les données métiers s'en contre foutent de savoir si ce sont des cercles ou des rectangles; et, encore plus, de savoir de quelle couleur sont ces formes. Tout ce qui les intéresse, c'est d'être en mesure de déterminer la position de l'élément au "tic" suivant et si ... l'espace occupé par l'une des donnée commence à "envahir" l'espace occupé par une autre.

    Alors, bien sur, tu vas sans doute me rétorquer que l'espace occupé par un des éléments dépend essentiellement de sa forme, mais c'est oublier un peu vite que la notion de formes vient avec une série d'informations et de services dont le modèle n'a que faire (comme le fait de connaitre la couleur, ou le fait de pouvoir l'afficher), et que tu peux éviter toute notion de forme si tu disposes du moyen de déterminer ... où s'arrête l'espace qu'elle occupe (par exemple, d'une formule permettant de calculer cette information).

    (3) Sur ce point là, je ne peux bien sur qu'être d'accord avec toi
    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

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 25/06/2011, 22h14
  2. Réponses: 2
    Dernier message: 30/12/2009, 20h44
  3. [Singleton] Class SQL qui fait planté le serveur
    Par Angelsafrania dans le forum ASP.NET
    Réponses: 6
    Dernier message: 25/06/2008, 13h22
  4. pb héritage sur classe abstraite et iterator
    Par black-falco dans le forum C++
    Réponses: 21
    Dernier message: 05/01/2008, 16h38
  5. polymorphisme, pointeurs et classes abstraites
    Par legend666 dans le forum C++
    Réponses: 10
    Dernier message: 02/11/2005, 16h44

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