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 :

[Problème] Surchage de fonction avec parametre ou retour hérité


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    11
    Points
    10
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 10
    Par défaut [Problème] Surchage de fonction avec parametre ou retour hérité
    Bonjour,
    je me retrouve face à une problèmatique que je crois être élémentaire et voilà ,en gros, de quoi il retourne.
    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
     
    class Comparable
    {
    	public :
    		Comparable(){};
    		virtual ~Comparable(){};
    		virtual int  compare(Comparable & _oCompareTo);		
    		//les fonctions ci dessous ne font qu'appeler la fonction ci dessus
    virtual void compare(Comparable & _oCompareTo, EComparison & _eComparison, EAmplitude & _eAmplitude);
    		virtual int  compare(Comparable * _pCompareTo);
    		virtual void compare(Comparable * _pCompareTo, EComparison & _eComparison, EAmplitude & _eAmplitude);
    };
    class StringCaracterizedObject : public Comparable
    {
    [...] //rien d'intéressant là dedans
    }
    class Attribute : public StringCaracterizedObject
    {
    	public :
    		//là, je pense overrider 'virtual int Comparable::compare(Comparable & _oCompareTo);' , j'analyse bien ?
                    virtual int compare(Attribute & _oCompareTo);
    }
    class AttributeFull : public Attribute
    {
    	public :
    //là pareil , je pense overrider 'virtual int Attribute::compare(Attribute & _oCompareTo);' , j'analyse bien ?
    	        virtual int  compare(AttributeFull & _oCompareTo);
    }
    void StratChoiceAttributeForCo::Execute(AttributeList * _pElectedList)
    {
    	for(AttributeTree::iterator it = m_pCandidates->begin();
    		it != m_pCandidates->end(); ++it)
    	{
    		Attribute * p = (Attribute*)(it.node->data);
    		if(p->GetValueString().compare("")!=0)
    			p = dynamic_cast<AttributeFull*>(p);
    		if(p)
    		{
    			std::string strCurentName = *p->GetPath();
    			int t = ConversionToolBox::sCombineComparisonAndAmplitude(m_eRefRelationType,m_eRefRelationAmplitude);
    			Attribute * pAttrib = m_pReference->Find(strCurentName);
    			if(pAttrib->GetValueString().compare("")!=0)
    				pAttrib = dynamic_cast<AttributeFull*>(pAttrib);
                            //Le problème vient de là : même si pAttrib et p sont convertis en AttributeFull, la fonction appelée est Attribute::compare()
                            int result = p->compare(*pAttrib);
    		}
     
    	}
     
    }
    Bref, j'ai un peu du mal à saisir le comportement du compilateur ou du programme à l'éxécution lorsqu'on a une hiérarchie du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class A
    {
         virtual int f(A* _a)
    }
     
    class B : A
    {
         virtual int f(B* _b)
    }
    Je m'attendrais à ce que, si le virtual n'est pas bien identifiée, B::f(B* _b) puisse être identifiée par sa signature... mais je crois que je loupe quelquechose. J'ai trouvé ce thread, mais il ne couvre pas le même problème il me semble.

  2. #2
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Points
    11 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Par défaut
    Citation Envoyé par vimes Voir le message
    je me retrouve face à une problèmatique que je crois être élémentaire et voilà ,en gros, de quoi il retourne.
    J'ai plutôt l'impression que tu cherches à faire des trucs que l'on ne fait pas en C++ (mélanger des éléments propres aux sémantiques de valeurs avec des hiérarchies polymorphes)

    Ton problème me semble plus relever du double-dispatch que du masquage.

    C'est quoi ton but ultime ? (question sous-entendue : pourquoi tous ces héritages?)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    11
    Points
    10
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 10
    Par défaut
    Je suis en train de bosser sur un système de semi-autonomous agent. Ces agents ont un component CoAttributes qui contient leur attributs (classe Attibutes i.e. nom et si nécessaire valeur) et un component CoGoals qui contient les objectifs sur des attributs qu'ils se fixent.
    Un aspect importants de la 'personnalité' d'un agent est la façon dont il sélectionne ses objectifs : i.e. quel attributs souhaite-il changer et de quelle manière.

    J'aimerais donc définir une famille de classes qui ont pour membre:
    - un type de relation seuil
    - une magnitude de relation seuil
    et qui possède une fonction Execute() qui prend en paramêtre
    - un container d'Attributs candidats C1
    - un container d'Attributs de référénce C2
    - un container d'Attributs élus C3
    dont le but est de constituer C3 d'éléments de C1 dont la comparaison via leur fonction compare() aux éléments de C2 réponds aux deux seuils fixés.

    Je suis en phase de prototypage pour l'instant,mais à terme j'aimerais que ces stratégies de choix soient applicables à tous types de Comparable... par exemple mes 'agents' seront de type Comparable et je voudrais pouvoir utiliser une même stratégie pour dire
    'choisissez tous les acteurs de C1 qui sont semblables en valeur à leur équivalent dans C2 avec une amplitude de 1/5' et
    'choisissez tous les attributs de C1 qui sont semblables en valeur à leur équivalent dans C2 avec une amplitude de 1/5'

    EDIT : j'ai différencié Attribute et AttributeFull pour gagner de la mémoire.En fait toutes les deux ont des fonctions set/getValue() mais seule AttributeFull à un membre correspondant : l'implémentation de ses fonctions dans Attribute renvoie des valeurs statique NAN ou "".

  4. #4
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    11
    Points
    10
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 10
    Par défaut
    J'ai trouvé une solution bien laide, mais qui a l'air de fonctionner :
    1. J'ai ajouté un enum EType, qui décrite le type d'une classe.
    2. Dans Comparable, j'ai ajouté un membre protected avec accesseur protected.
    3. Pour chaque sous-classe C qui hérite directement ou indirectement de Comparable :
      1. je set m_eMetaType dans le(s) constructeur(s).
      2. j'overload int Comparable::compare(Comparable & _oCompareTo) par une fonction du type
        Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
         
        int C::compare(Comparable & _oCompareTo)
        {
        	int iValue = 0
        	if(m_eMetaType == EType_C)
        		iValue = compare(*(C*)(&_oCompareTo));
                else
                        iValue = ParentClass::compare(_oCompareTo);
        	return iValue;
        }
        Evidemment, ça ne marche pas si C hérite de 2 classes héritant elles-même de C directement ou indirectement, mais ça ne devrait pas avoir lieu.
      3. je définis une fonction int compare(C & _oCompareTo) qui est propre au contenu de C.

    Ca me permet de faire des Stratégie qui fonctionnent sur des Comparable mais qui appelle les fonctions compare les plus précises.
    Z'en pensez quoi ?
    Je passerai le topic en Résolu plus tard si il n'y a pas d'objections à cette méthode.

  5. #5
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Points
    495
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Par défaut
    J'ai vraiment pas suivi cette discussion (et je me sens pas de la lire maintenant), alors juste quelques petites remarques :
    Citation Envoyé par vimes Voir le message
    j'overload int Comparable::compare(Comparable & _oCompareTo) par une fonction du type
    Tu "overload" (tu surcharges)?

    Ou bien tu "override" (tu supplantes)?

    Citation Envoyé par vimes Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iValue = compare(*(C*)(&_oCompareTo));
    Tu peux faire directement un cast de référence :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     compare((C&) _oCompareTo);
    qui est quand même moins lourd syntaxiquement, et strictement équivalent (quoi que le cast original signifie).

    Si tu veux caster d'une classe de base à une classe dérivée, utilises plutôt static_cast :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     compare(static_cast<C&> (_oCompareTo));
    Au fait, quelle est la sémantique de compare? (En particulier, qu'est-ce que compare() == 0 signifie?)

  6. #6
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Points
    6 911
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Par défaut
    Citation Envoyé par vimes Voir le message
    Z'en pensez quoi ?
    Que tu ferais mieux de suivre la suggestion de Luc et de faire une recherche sur double dispatch (ou sur visiteur, un pattern qui en a besoin et dans les explications duquel on trouve donc souvent une explication du double dispatch).

    En passant, il y a une certain nombre de paramètres que je me serais attendu à voir const et qui ne le sont pas.

  7. #7
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    11
    Points
    10
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 11
    Points : 10
    Par défaut
    Merci pour les commentaires.
    Pour les paramêtres en const tu as raison, faudra que je change ça.
    J'avais pensé à utiliser le pattern visitor pour le compare(), mais je l'avais écarté... maintenant que j'y pense, je ne sais plus trop pourquoi. Je vais reconsidérer ça.Merci pour le rappel

    Tu "overload" (tu surcharges)?Ou bien tu "override" (tu supplantes)?
    Je supplante

    Tu peux faire directement un cast de référence.
    Si tu veux caster d'une classe de base à une classe dérivée, utilises plutôt static_cast :
    OUla, j'ai rushé sur le code et ça se sens. Merci de ta vigilance.
    Au fait, quelle est la sémantique de compare? (En particulier, qu'est-ce que compare() == 0 signifie?)
    La valeur de retour de compare est la composition de deux Enums :
    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
     
    enum EComparison //qualifie le type de relation
    {
    	EComparison_UNRELATED = 0,
    	//Related in nature
    	EComparison_REL_NAT = 1,
    	//Related in 'value'
    	EComparison_REL_VAL = 2,
            //same value, same nature
    	EComparison_IDENTICAL = 3,
    	//same object
            EComparison_SELF = 4,
    };
    enum EAmplitude // qualifie l'amplitude de la relation
    {
    	EAmplitude_NONE = 0,
    	EAmplitude_SMALL = 1,
    	EAmplitude_MEDIUM = 2,
    	EAmplitude_HIGH = 3,
    };
    que je compose ou que j'extrais d'un int via les fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	static int sCombineComparisonAndAmplitude(const EComparison & _eComparison,const EAmplitude & _eAmplitude);
    //return (int)eComparison*10+_eAmplitude
    	static void sExtractComparisonAndAmplitude(const int & _iValue, EComparison & _eComparison,EAmplitude & _eAmplitude);
    Je me demande s'il ne vaudrait pas mieux que je crée une classe de résultat de comparaison, mais à ce stade, j'ai du mal à y voir un avantage.

Discussions similaires

  1. [EasyPHP] Fonction avec parametre par référence et EasyPHP 1.8
    Par niaxon dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 9
    Dernier message: 01/02/2007, 11h59
  2. appel d'une fonction avec parametre.
    Par rollernox dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 13/10/2006, 00h07
  3. Problème onclick/lien/fonction avec IE
    Par kankrelune dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 21/06/2006, 18h46
  4. créer une fonction avec parametre optionnel
    Par maximenet dans le forum Langage
    Réponses: 2
    Dernier message: 29/01/2006, 21h51
  5. fonction avec parametre
    Par donny dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/06/2005, 12h31

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