IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Comment surcharger une fonction avec comme différence de signature objet de base & dérivées ?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club Avatar de silversthan
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Novembre 2006
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 4
    Par défaut Comment surcharger une fonction avec comme différence de signature objet de base & dérivées ?
    Salut les codeurs,

    Voila j'aimerai faire une surcharge de fonction qui affichera le contenu voulu selon l'argument, ici des objets de base et ses dérivées :

    par exemple :
    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
     
        class Base
        {
           //...
        };
        class Banana : public base
        {
            //...
        };
        class Apple : public base
        {
            //...
        };
     
        class Render
        {
            //...
            void draw (Base * base){/*...display base...*/}
            void draw (Banana * banana){/*...display banana...*/}
            void draw (Apple * apple){/*...display apple...*/}
        };
     
        vector<Base*> fruits;
        Render myRender;
     
        fruits.emplace_back(new Banana());
        fruits.emplace_back(new Apple());
        fruits.emplace_back(new Banana());
     
        for (unsigned int i(0); i<fruits.size(); ++i)
        {
            myRender.draw(fruits[i]);
        }
        //... affiche :<br>    // base base base
    Le soucis c'est qu'il finit par afficher que l'objet de base !

    Peut-être un défaut de conception, mais je voudrais séparer les Renderer et les Objets.

    Avez vous un solution élégante pour résoudre ce problème ?

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Les types des arguments c'est du typage statique. Seul un pattern visiteur pourra te sortir de là.
    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.

  3. #3
    Membre chevronné
    Avatar de Garvelienn
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2016
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

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

    Informations forums :
    Inscription : Septembre 2016
    Messages : 244
    Par défaut
    Déjà, c'est logique que seuls les objets de Base soient affichés. Dans ton vecteur, tu ne stockes que des pointeurs de type Base. Lorsque tu lui donnes des pointeurs de Banana, le vecteur le cast en Base*. Du coup, le vecteur ne mémorise pas que c'est une objet Banana. Ainsi seule la méthode Render::draw(Base*) est appelée.

    Je vois deux solutions:
    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
     
    class Render
    {
      void drawABase(Base* b)
      {
        Banana* banana;
        Apple* apple;
        if (banana = dynamic_cast<Banana*>(b))
        {
          this->draw(banana);
        }
        else if (apple = dynamic_cast<Banana*>(b))
        {
          this->draw(apple);
        }
        else
        {
          this->draw(b);
        }
      }
       void draw(Base* b);
       void draw(Banana* b);
       void draw(Apple* b);
     
    }
    Il y a plus esthétique mais c'est l'idée.

    Sinon de la POO pure:
    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
     
    class Base
    {
           virtual void draw();
    };
    class Banana : public base
    {
            virtual void draw() override;
    };
    class Apple : public base
    {
            virtual void draw() override;
    };
     
    class Render
    {
       void draw (Base * base) { base->draw(); }
    };
    Tout dépend de ton architecture et de tes besoins en fait

  4. #4
    Futur Membre du Club Avatar de silversthan
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Novembre 2006
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 4
    Par défaut
    Merci pour vos réponses ^^

    En faite le but ici serai de séparer les objets et ces dérivées du render(), je ne veux en aucun cas utilisé des méthodes d'API graphique/sonore/input/etc dans les classes Base, Apple, Banana, etc.

    Garvelienn , ton premier listing semble mieux se rapprocher de ce que je voudrai, par contre je pense qu'il y a quelque faute de frappe pour les "=" au lieu de "==" et à la ligne 12 "(apple = dynamic_cast<apple*>(b)".
    C'est pas bien grave j'avais compris l'idée . En gros c'est un draw() selectif selon le cast, sinon que pense-tu de typeId plutôt ?

    Je vais jeter un oeil sur le Pattern visitor !

  5. #5
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par silversthan Voir le message
    par contre je pense qu'il y a quelque faute de frappe pour les "=" au lieu de "==" et à la ligne 12 "(apple = dynamic_cast<apple*>(b)".
    Non ce n'est pas un défaut de frappe, d'ailleurs il faudrait aussi mettre la déclaration dans le if au lieu de tout déclarer en début de fonction.
    Mais cette solution est de loin la moins bonne. Les dynamic_cast ne devraient pas être utilisés à cette fin.

    Ton exemple en lui-même montre plus une erreur de conception qu'autre chose.
    Banane et Apple sont des objets gameplay/métier. Ils n'ont rien à voir avec l'affichage en soit.
    L'affichage devrait fournir une classe qui permette de transformer les informations de ces objets en truc à afficher.
    Dans le cas d'un jeu 2D, tu as une classe Sprite. Que tu aies une banane, apple ou n'importe quoi, tu instancies un Sprite et lui donne les infos relatives à l'affichage (texture, position, taille, ....)
    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.

  6. #6
    Futur Membre du Club Avatar de silversthan
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Novembre 2006
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 4
    Par défaut
    Merci, autant pour moi !

    Je vois beaucoup mieux l'approche, je vais essayer de revoir ma conception. Bien que je voudrai continuer à séparer objet/gameplay/métier de l'affichage.

  7. #7
    Membre chevronné
    Avatar de Garvelienn
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2016
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

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

    Informations forums :
    Inscription : Septembre 2016
    Messages : 244
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Les dynamic_cast ne devraient pas être utilisés à cette fin.
    Petite question : en quoi est-ce gênant ? Est-ce une question d'efficacité ?

    Pour le reste, je restais volontairement abstrait. D'où ma dernière phrase: "Tout dépend de ton architecture et de tes besoins en fait"

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  2. Comment "surcharger" une fonction "statique" ?
    Par ZZZzzz2 dans le forum Langage
    Réponses: 5
    Dernier message: 09/07/2012, 17h39
  3. [AC-2003] Comment appeler une fonction avec deux paramètres. Erreur '=' attendu
    Par nirG95 dans le forum VBA Access
    Réponses: 1
    Dernier message: 02/09/2009, 10h53
  4. surcharge de fonction avec comme paramètre Object
    Par poporiding dans le forum C++
    Réponses: 8
    Dernier message: 14/07/2006, 03h47
  5. comment intgrer une fonction en excel avec delphi
    Par kious dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 02/05/2006, 18h15

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