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 :

Probleme appel des gestions de classes / appelles de methodes


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 13
    Points : 6
    Points
    6
    Par défaut Probleme appel des gestions de classes / appelles de methodes
    Bonjours tout le monde,
    Je débute en C++ et j'apprend un peu "sur le tas",e t la je suis face à un probleme qui commence a me titiller severement...
    Il est fort possble que ce probleme découle d'une mauvaise comprehension de l'OO, mais je débute et j'apprend "sur le tas"...
    En Gros mon probleme.
    jai une class A(IProblem) dont je veux me servir comme "interface" (enfaite jai repris du code Java que j'ai tanter de traduire en C++... en sachant que je ne metrise ni l'un..ni l'autre...)
    Une classe B(CaM) qui implemente ces methodes
    et pour terminer une class C(ISolver) qui va faire des actions sur des objet A mais je veux que ce soit "traiter" par ma class B ... Enfin c'est compliquer, et je suis un peu dans le flou au niveau des concept et de la terminologie OO.. Voila mon code (c'est un peu brut, mais j'ai essayer de supprimer des choses inutiles).
    Il y'a des choses qui vont vous apraitre abherrante (genre des attribut public ...) mais je tatonne, j'avance bout par bout.... Et j'aimerais bien avoir un resultat avant de me lancer dans le relifting "propre" de mon code...
    Si quelqu'un m'a suivit jusque là et ce sent le courage de jetter un oeil...




    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
    #ifndef _GENERIC
    #define _GENERIC
    #include <string>
    #include <list>
    #include <iostream>
     
    using namespace std;
     
     
    class IState{
    	public:
    		virtual void printState() =0;
     
    };
     
     
    class aCaMState : public IState{
     
    	public:
    		int nbMr_, nbCr_, nbMl_, nbCl_;
    		string pos_;
     
    	public:
    		aCaMState(int nbMl, int nbCl,int nbMr, int nbCr,string pos){
    //.....
    		}
     
    };
    La classe IState est une "interface" au sens java de la classe aCamState. L'idée c'est de pouvoir travailler avec des "interfaces" peut importe leur implementation..


    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 IProblem{
     
    	public :
    		//----- methods -----
    		virtual IState * INIT()=0;
    		virtual bool GOAL( IState * state_ ){};
    		virtual list<Triplet *> SUCCESSOR_FN( IState * state_ ){};
    };
     
     
    class CaM : public IProblem{
     
    	public:
    		aCaMState * INIT(){return new aCaMState(0,0,3,3,"D");}
    		bool GOAL(aCaMState * state_ ){//implementation... }
     
    		virtual list<Triplet *> SUCCESSOR_FN( aCaMState * state_ ){//implementation... };
    };
    La classe don CaM, qui est une implémentation de la classe IProblem. C'est là que les choses commencent à être délicates...

    J'essaye d'expliquer clairement :
    les ISlover (dont ci-dessous on a une implémentation sous la forme d'un treeSearch) doivent pouvoir manipuler des IProblem sans avoir à ce soucier de leur "type" exact (ici CaM), et le but est justement de pouvoir jouer avec différentes "implémentations" des interfaces "abstraites" sans avoir à modifier celles-ci.


    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 ISolver{
     
        //----- methods -----
     
    	public:
    		virtual void SOLUTION( Node * node_ ) {};
     
    		list <Node *> EXPAND( IProblem * problem_, Node * node_ ){
    //...implementaiton de la fonction
    		}
     
     
    };
     
    class treeSearch : public ISolver{
    	public :
     
    	void SOLUTION(Node * node_){
    		//....
    	};
     
     
    	 treeSearch( IProblem * problem_, list<Node *> fringe_ )
    		{
    			fringe_.push_back( new Node( problem_->INIT() ) );
    			do
    			{
    				Node * node = * fringe_.begin();
    				fringe_.pop_front();
     
    				cout<<node->ACTION()<<endl;
    				(node->STATE())->printState();
    				cout<<node->DEPTH()<<endl;
     
     
    				if( problem_->GOAL( node->STATE() ) ) //la fonction GOAL utilisée est celle déclarée dans IProblem 
    				{
    					SOLUTION( node );
    					break;
    				}
     
    				fringe_.insert(fringe_.end(), EXPAND( problem_, node ).begin(),EXPAND( problem_, node ).end() );
    			}
    			while( !fringe_.empty () );
    		}
    };
     
    #endif

    Le problème ce situe donc ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    				if( problem_->GOAL( node->STATE() ) ) //la fonction GOAL utiliser est celle déclarer dans IProblem 
    				{
    					SOLUTION( node );
    					break;
    				}
    node->STATE renvoie effectivement un ISTate, et la fonction appeler est donc GOAL() déclarer dans IProblem, hors j'aimerais que ce soit celle de CaM (enfaite en general de la classe fille de IProblem).

    Voici aussi la classe Node que j'aurais peut-Être du mettre dès le départ...:

    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
    class Node{
     
    	private:
    		int    depth;
    		int    path_cost;
    		Node * parent;
    		IState * state;
    		string action;
     
    	public:    //----- accessors -----
                 //.....
    		//----- constructors -----
    		Node ( IState * state_, Node * parent_, string action_,
    		     int path_cost_, int depth_ ){}
    		Node ( IState * state_ ){}
     
    };
    Je me demande si des templates, en lieu et place de mes bancales "virtual pures" fonctions, ne resoudrait pas mon problème... Enfin je suis toujours preneur des idées de personnes plus rigoureuses et renseignée que moi....

  2. #2
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Citation Envoyé par Sykaa Voir le message
    [...]Si quelqu'un m'a suivit jusque là [...]
    Jusque là, oui, mais avec difficulté, non pas à cause du sens mais de la forme. essaye de passer tes textes au correcteur orthographique minimal (celui de firefox suffit) ou relit toi avant de poster un message.

    D'autre part, quelque-soit l'épuration que tu a appliquée à ton code, je doute qu'on y trouve ce que tu cherche si tu ne nous dis pas ce qui te pose problème :
    Nous comprenons que tu aie des difficultés et.... rien ?

    Veut -tu un avis sur ton code ? (manque cruellement de commentaires)
    Une correction ? (mais indique nous quelles erreurs tu reçoit) (je ne crois pas qu'on puisse mettre des "=0" après les fonctions même virtuelles mais je suis pas sûr)
    Un conseil ? (sur quoi ?) (c'est une mauvaise idée d'adapter si tu ne comprend pas (si jamais ça compile, il y as de bonne chance pour que le résultat ne soit pas bon), sinon, mieux vaut recoder que d'emporter la pléthore d'erreurs liées au transfert)

    Bref, je doute que beaucoup de personnes veuillent t'aider si tu ne fait pas l'effort minimal de présentation, et je pense qu'encore moins ne le pourrons êtant donné que tu ne nous donne pas la queue d'une piste pour résoudre ton problème qu'on ne connait pas...

    Je te souhaite néanmoins bonne chance
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Enfaite le problème est assez "simple" dans son identification :
    Lors de l'appel de la fonction GOAL, dans la classe TreeSearch, c'est la fonction de la classe "IProblem" qui est appelée (et qui doit retourner "true" par défaut puisque ça sort de ma boucle if) hors, je voudrais que ce soit celle de la classe "CaM".
    Il n'y a pas d'erreur de compilations, juste ce problème là, et je n'arrive pas à trouver de solution.
    J'ai essayer de faire quelque chose comme CaM::GOAL, mais g++ me dit que CaM "is not a base of 'IProble' ".
    Désolé pour les fautes et "la forme", et merci de m'avoir répondu.
    J'espère que mes quelques ligne ci-dessus convaincront d'éventuels bienfaiteurs de m'apporter leur aide...

  4. #4
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Les deux fonctions GOAL de la classe IProblem et CaM ne prennent pas les mêmes types d'arguments et ont par conséquent des signatures différentes: il y a donc surcharge de l'une par l'autre, la fonction appelée est donc celle qui correspond au type de la variable.
    Dans ce cas, même si les deux types sont hérités l'un de l'autre, c'est la fonction compatible avec le type passé en argument qui est appelée.

    Apparemment, node->STATE() renvoie le type IState et non aCaMState ( aCaMState peut être géré comme un IState, mais je ne crois pas que l'inverse soi possible).

    Sinon, essaye d'éditer ton premier post et découpe ton code en plusieurs morceaux pour que ce soit lisible, isole la ligne de ton erreur (rien ne t'empêche de l'écrire deux fois) et n'hésite pas à faire de très long poste commentés par des phrases concises mais précises et découpées.

    Bonne chance toutefois pour ton projet.
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Merci pour tes conseils, je suis sur un autre projet (en Perl) pour le moement mais dès que j'ai le temps je remets tous ça en forme.
    Il faudrait que je cast alors le IState en aCaMState? enfin je me repencherais sur le problème dans quelques heures.
    Merci encore.

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    J'ai suivi les conseils méphisto et remis quelque peut en forme mon message initial... J'espère que c'est plus parlant, mais tout comme en C++, je débute aussi en developpez.net .
    Enfin tou(te)s critiques/conseils sont les biens venu(e)s

  7. #7
    Membre éprouvé
    Avatar de méphistopheles
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    1 551
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 1 551
    Points : 1 220
    Points
    1 220
    Par défaut
    Heuuu, il manque la methode STATE de ta classe node même si on se doute un peu de ce qu'elle fait.

    Comme je te l'ai dit, tu ne peut pas appeler le Goal de la classe Cam avec un Istate en argument.

    Par contre, si tu a une constructeur du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Cam(const Istate & convert);
    dans ta Classe Cam, tu pourrais faire quelque chose du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    problem_->GOAL( Cam(node->STATE()) )
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    problem_->GOAL( node->STATE() )
    Ce qui te permettra de résoudre ton problème.

    Bonne chance

    Note: C'est mieux pour la présentation, mais essaye de trier: par exemple, la déclaration de aCamState ne sert pas à grand chose. Essaye d'avoir des boites de codes suffisamment petites pour qu'on aie pas besoin d'utiliser les scrollbar (quitte à mettre tes commentaires sur plusieurs lignes).
    Méphistophélès
    Si la solution ne résout pas votre problème, changez le problème...
    Cours et tutoriels C++ - FAQ C++ - Forum C++.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Oui, effectivement, ça marche, même en castant simplement en faisant (CaM*) ( cast qui n'a pas besoin d'être défini).
    Pour être exact il faut caster le paramêtre de la methode pour qu'il corresponde à la bonne signature, et l'objet appelant la methode... enfin voilà exactement ce qui marche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((CaM*)problem_)->GOAL( (aCaMState *)node->STATE() )
    Le problème avec ce cast, c'est que imaginons je defini une nouvelle classe DbN déerive de IState (tout comme CaM) et une autre aDbNState dérive de IState (tout comme ( aCaMState ) j'aimerais bien ne pas avoir à recaster à chaque fois...

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ça ressemble à un problème de Double Dispatch.
    Si c'est le cas, renseigne-toi sur le pattern Visitor, mais je ne suis pas sûr qu'il puisse t'aider dans le cas présent...

    Sinon, je te propose ceci:
    Code C++ : 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
    class CaM : public IProblem {
     
    public:
    	aCaMState * INIT(){return new aCaMState(0,0,3,3,"D");}
    	bool GOAL(IState * state_ )
    	{
    		aCaMState * state2 = dynamic_cast< aCaMState * >(state_);
    		if(state2 != NULL)
    			return GOAL(state2);
    		else
    		{
    			//Ce que tu veux faire quand state_ n'est pas un aCaMState...
    		}
    	}
    	bool GOAL(aCaMState * state_ ){//implementation... }
    };
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 13
    Points : 6
    Points
    6
    Par défaut
    Je vais me renseigner un peu sur ces Visitor, mais sinon t'as solution à part l'air trop mal.. Si j'ai bien compris dans chaque classe dérivée je définie un espèce de methode de "passage" pour choisir si c'est le bon cast ou non?

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/02/2009, 18h06
  2. Appel des class C++ depuis C#
    Par bouzaidi dans le forum C++
    Réponses: 2
    Dernier message: 08/10/2008, 17h26
  3. Probleme dans l'appel des programmes systeme
    Par khalid_kha dans le forum Langage
    Réponses: 1
    Dernier message: 14/08/2008, 18h44
  4. appel des elements d'une classe à partir d'une autre
    Par oceane751 dans le forum Langage
    Réponses: 4
    Dernier message: 02/01/2008, 21h52
  5. Probleme d'appel des jsp(avec balise struts) par ajax
    Par edogawa dans le forum Struts 1
    Réponses: 1
    Dernier message: 23/08/2007, 23h14

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