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

Langage C++ Discussion :

héritage virtuel multiple


Sujet :

Langage C++

  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Par défaut héritage virtuel multiple
    Bonjour,

    j'aurais besoins de vos lumières

    J'ai déjà regardé par-ci par-là différents articles, mais je n'ai pas trouvé ce que je cherche ou je n'ai pas compris les solutions qui étaient présentées.

    Voici la liste des différents objets que j'aimerai définir.
    Contrainte: classe définissant des propriétés sur les contraintes. Contient des méthodes virtuelles pures et d'autres non pure.
    IntegerContrainte: une contrainte sur les entiers dispose d'une propriété en plus que les autres contraintes. Propriété définie par méthode virtuelle pure
    ConjonctionContrainte : C'est une contrainte qui implémente les méthodes virtuelles pures de la classe Contrainte
    Addition: une contrainte sur les entiers: défini les méthodes virtuelles pures de "Contrainte" et "IntegerContrainte"
    ConjonctionIntegerContrainte : C'est une "ConjonctionContrainte" qui doit également implémenter les méthodes de "IntegerContrainte"

    Malheureusement, je ne sais pas exactement comment je dois définir la hiérarchie de classe. Pour l'instant, j'ai défini dans "IntegerContrainte" uniquement la méthode virtuelle pure liée aux contraintes sur les entiers et donc la classe Addition hérite de Contrainte et IntegerContrainte. Je me suis dit qu'en faisant ainsi je sépare bien les choses et je n'ai pas d'ambiguïté pour les appels aux fonctions.
    Cependant, le soucis que je rencontre actuellement, c'est que lorsque j'appelle la fonction relative aux contraintes sur les entiers de ma classe "Addition", ce n'est pas la bonne fonction qui est exécutée

    Voici ce à quoi ressemble le code:
    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
     
    template<typename T>
    class Constraint {
    public:
      virtual ~Constraint() { }
      virtual bool isSatisfiable() const throw (ConstraintException) = 0;
      virtual bool nodeConsistent() { ... }
    }
     
    template<typename T>
    class ConjunctionConstraint : public Constraint<T> {
    public:
      virtual bool isSatisfiable() const throw (ConstraintException) { ... }
      virtual bool nodeConsistent() {...}
    }
     
    class IntegerConstraint {
    public:
      virtual ~IntegerConstraint() {...}
      virtual bool boundsConsistent() = 0;
    }
     
    class AdditionConstraint : public Constraint<int>, public IntegerConstraint {
    public:
      virtual bool boundsConsistent() {...}
      virtual bool isSatisfiable() const throw (ConstraintException) { ... }
      virtual bool nodeConsistent() {...}  
    }
     
    //ne contient qu'une seule méthode: celle nécessaire pour IntegerConstraint, se repose sur les implémentations de ConjunctionConstraint pour tout le reste
    class IntegerConjunction : public ConjunctionConstraint<int>, public IntegerConstraint {
    public:
      virtual bool boundsConsistent(){
        ...
        Constraint<int>* c = itc->next();
        if (dynamic_cast<IntegerConstraint*> (c)) {
          IntegerConstraint* ic = (IntegerConstraint*) c;
          bc = ic->boundsConsistent();
        }
        ....
      }
    }
    Et le soucis, c'est qu'au moment où il faut effectuer ic->boundsConsistent(); (la deuxième fonction virtuelle de IntegerConstraint), un appel est effectué à la fonction "isSatisfiable" (qui est la deuxième fonction virtuelle de Constraint) au lieu d'appeler la bonne fonction.

    J'ai cru voir que je dois éventuellement ajouter des "virtual" lorsque je déclare l'héritage. J'ai fait des essais mai je pense pas avoir bien compris car je n'ai rien obtenu de concluant

    Donc je me pose la question de savoir comment je dois organiser ma hiérarchie? Si vous avez des idées, je suis preneur :-)

    PS: j'ai plus d'expérience en java ce qui fait que je n'ai peut-être pas la bonne pratique pour des spécificités du C++ ...

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IntegerConstraint* ic = (IntegerConstraint*) c;
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IntegerConstraint* ic = dynamic_cast<IntegerConstraint*>(c);

  3. #3
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Par défaut
    En effet, ça fonctionne ainsi. Je passe le sujet en résolu

    note à moi même: ne plus jamais faire un cast normal...

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par luckyvae Voir le message
    note à moi même: ne plus jamais faire un cast normal...
    Tu peux étendre cette note à tout développeur C++
    Et tant qu'à faire un cast normal en C++, c'est un bidule_cast<>(). Sinon, c'est un cast pas normal
    [EDIT] : t'as une idée pourquoi ?

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

Discussions similaires

  1. Héritage virtuel et constructeur.
    Par Klaim dans le forum C++
    Réponses: 17
    Dernier message: 10/01/2015, 21h18
  2. Question sur l'héritage virtuel
    Par ezsoft dans le forum C++
    Réponses: 10
    Dernier message: 20/08/2008, 09h13
  3. template, héritage virtuel: gcc vs Visual II
    Par 3DArchi dans le forum Langage
    Réponses: 5
    Dernier message: 07/08/2008, 15h53
  4. Héritage Virtuel et SDL
    Par Qualimero dans le forum SDL
    Réponses: 6
    Dernier message: 18/07/2006, 04h49

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