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 :

fonction virtuelle utilisant les méthodes des classes dérivées


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 9
    Points : 4
    Points
    4
    Par défaut fonction virtuelle utilisant les méthodes des classes dérivées
    Bonjour,

    Mon problème est le suivant:
    J'ai une classe virtuelle Objet dont dérivent différentes classes, par exemple Sphere, Cube...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class Objet;
    class Sphere : public Objet
    class Cube : public Objet
    J'ai une fonction virtuelle pure membre de Objet qui prend en argument un pointeur vers un objet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual void Objet::fonction(Object* obj) = 0;
    cette fonction est définie dans les classes dérivées
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     //void Sphere::fonction(Object* obj) = 0;
     //void Cube::fonction(Object* obj) = 0;
     //edit: erreur de recopie
     void Sphere::fonction(Object* obj);
     void Cube::fonction(Object* obj);
    Cette fonction utilise des méthodes définies uniquement dans les classes dérivées.
    Bien entendu le compilateur râle: 'class Objet' has no member named 'toto'
    puisque toto n'est défini que dans les classes dérivées et pas dans la classe mère.

    Comment contourner ce problème? A part en faisant en sorte que toutes les fonctions soient définies dans la classe mère (vituellement bien sûr!)
    Merci d'avance pour votre aide

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 23
    Points : 31
    Points
    31
    Par défaut
    Salut,

    Dans ton post tu écris :
    cette fonction est définie dans les classes dérivées
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     void Sphere::fonction(Object* obj) = 0;
     void Cube::fonction(Object* obj) = 0;
    Or quand tu écris ça tu ne définis pas les fonctions...
    Je pense que la solution à ton problème est d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Objet
    {
    virtual void fonction(Object* obj) = 0;
    }
    puis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Sphere : public Object
    {
    virtual void fonction(Object *obj);
    }
    Et dans Sphere.cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void Sphere::fonction(Object *obj)
    {
    // ... ce que tu veux
    }

    Si ce n'est pas exactement la réponse que tu attend, merci de mettre un peu plus de détail sur ton code.

    Cordialement,




    -------------------
    Adrien BARRAL
    REETI's Development team
    http://www.reeti.fr

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Merci pour ta réponse abarral, mais la fonction est bien définie dans les classes Sphere et Cube. C'est par erreur qu'en créant le post, j'ai mis = 0, je vais éditer mon premier message pour le corriger.
    Tu as sans doute raison, je devrais expliciter davantage mon problème, voici donc le code plus en détails (mais quand même résumé):

    Dans Object.h:
    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
     
    enum ObjType {
      OBJ_CUBE,
      OBJ_SPHERE,
    };
    class Object
    {
      protected:
        ... //différentes données sur le maillage (par exemple position)
      public:
        ObjType type; //définit le type de l'objet
        ... //constructeur et différentes fonctions
        //fonction virtuelle pure pour le calcul d'intersection
        virtual bool intersecte(Object* obj) = 0;
    }
    Dans Sphere.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class Sphere : public Object
    {
      private:
        float radius;
      public:
        ... // constructeurs 
        float GetRadius() { return radius; }
        void  SetRadius(float _radius) { radius=_radius; }
        ... // fonctions pour créer le maillage
        bool intersecte(Object* obj);
    };
    Dans Sphere.cpp:
    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
     
    #include "Sphere.h"
    ... // définition des constructeurs et des fonctions pour créer le maillage
    //cherche et calcule les intersections
    bool Sphere::intersecte(Object* obj)
    {
      bool result = false;
      switch(obj->type)
      {
        case OBJ_SPHERE:
          // cette fonction a besoin de données membres de Sphère, par exemple:
          this->getRadius() // marche puisque l'on est dans la classe Sphère
          obj->getRadius() // -> erreur du compilateur: la Classe Object n'a pas de  membre nommé getRadius()
          break;
        case OBJ_CUBE:
          // cette fonction a besoin d'accéder aux membres de Cube -> erreur du compilateur
          break;
      }
      return result;
    }
    De même, on a des problèmes similaires dans Cube.h et Cube.cpp
    (Note: j'ai également plein d'autres classes dont je ne parle pas ici: Quad.h Grille.h ObjModel.h ....)

    Je vois pour l'instant deux solutions aux problèmes (mais aucune ne me plait):
    -1ère solution:
    Définir plein de fonctions virtuelles dans Objet.h pour chacune des fonctions définies dans les classes dérivées.
    Par exemple rajouter dans Objet.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    virtual float getRadius() { return 1.0f; }
    -2ème solution: (qui me plait un peu plus)
    ne pas faire de fonction intersecte(Objet*) mais plein de fonctions spécifiques que l'on appelera en fonction du type des objets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    intersecteSphere(Sphere* sph);
    intersecteCube(Cube* cub);

  4. #4
    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 : 49
    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
    Tu veux faire du multiple dispacth, ce qui n'est pas directement possible en C++ aujourd'hui. Des alternatives plus ou moins bien existent, voir par exemple http://en.wikipedia.org/wiki/Multiple_dispatch#C.2B.2B
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Merci pour ta réponse JolyLoic, le "dynamic_cast" semble être ce que je recherchais. Toutefois, après réflexion j'ai décidé d'utiliser la solution 2, principalement pour diminuer la taille de la fonction intersecte(Object* obj), qui devient très grande (et moins lisible) à cause de tous les cas possible.
    En tout cas, merci beaucoup pour votre aide, qui m'a permit de découvrir "dynamic_cast" que je ne connaissait pas.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Salut,

    C'est peut être un peu tard pour ajouter une réponse mais je le fais quand même.

    eskato je ne comprends pas pourquoi dans ta fonction Sphere::intersect(Object *o) tu traite aussi les cas ou au lieu de passer une Sphere tu aurais passé un cube????? Ce qui veut dire que soit ton o est une sphere soit tu génère une exception ou autre chose pour prévenir que l'objet passé ne correspond pas à une Sphere

    Normalement dans ta (tes) fonction(s) Sphere::.... tu ne traite que les Spheres sinon pourquoi faire de la programmation Objet?

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Bonjour,

    Désolé de ne répondre que maintenant, mais je n'ai pas probablement activé l'option d'avertissement par mail (à propos, vous savez comment on fait?)
    Sinon, pour répondre à ta question, le moteur doit être capable de simuler les chocs sphere-sphere, mais aussi sphère-plan, sphere-cube, et autres...
    C'est pour cela que j'ai besoin d'une fonction d'intersection de la sphère avec les autres types d'objets.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/05/2009, 12h31
  2. Réponses: 10
    Dernier message: 28/08/2008, 18h15
  3. Réponses: 4
    Dernier message: 27/07/2007, 18h18
  4. Réponses: 1
    Dernier message: 10/05/2006, 19h45
  5. Utiliser les méthodes des boutons crées en rafale.
    Par kabouns dans le forum Composants
    Réponses: 8
    Dernier message: 03/12/2004, 10h48

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