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 :

Equivalent en C++ classes internes anonymes en Java


Sujet :

C++

  1. #1
    Membre r�gulier
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes C�te d'Azur)

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut Equivalent en C++ classes internes anonymes en Java
    Bonsoir,
    je suis actuellement sur un projet d'outils ecrits en C++ pour la librairie SDL.
    Ces outils permettent de cr�er et de manipuler un moteur de jeu, une banque de son, des fichiersde ressources et de configurations, pour faciliter la cr�ation d'un jeu vid�o en 2D. Une bo�te � (GUI)widget est �galement incluse. Mon probl�me survient dans l'interaction entre l'utilisateur et les widgets. L'organisation des classes est la suivante:

    - Classe Abstraite Widget.
    |-> Menu (h�rite de Widget)
    |-> DialogBox (h�rite de Widget)
    |-> etc...

    Chaque Widget dispose d'un certain nombre de WidgetItem.

    - Classe Abstraite WidgetItem
    |-> TextLabel (h�rite de WidgetItem)
    |-> ImageLabel (h�rite de WidgetItem)
    |-> etc...

    C'est en interagissant (par double clique) sur les WidgetItem que l'on d�clenche des actions. Chaque widget doit �tre capable de r�aliser une action sp�cifique et dispose donc d'une m�thode "action()" virtuelle pure qu'il faut d�finir dans une classe fille. Il est fastidieux d'�crire une nouvelle classe h�ritant de TextLabel (ou autre classe h�ritant de WidgetItem) pour d�finir l'action sp�cifique � r�aliser.
    Ma question est donc la suivante: existe t-il un m�canisme proche de celui du Java en C++ pour cr�er des classes internes anonymes.

    Exemple en Java:
    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
    public interface Action {
    void do_something();
    }
    ...
    public class TextLabel {
        private Action action;
     
        public void add_action(Action a) {
            action = a;
        }
     
        public void action() {
            a.do_something();
        }
    }
    ...
    public class Menu {
         private int a;
         private TextLabel label;
     
         public Menu() {
             label = new TextLabel();
             label.add_action( new Action() {
                                         void do_something() {
                                              // implémentation de l'interface
                                              // la classe interne a accès aux éléments de Menu
                                              a++;
                                         }
             });
             label.action()         // augmente le membre "a" de 1
             label.add_action( new Action() {
                                         void do_something() {
                                              // implémentation de l'interface
                                              // la classe interne a accès aux éléments de Menu
                                              a--;
                                         }
             });
             label.action()         // reduit le membre "a" de 1
        }
    }
    La seule solution que j'ai trouv� pour l'instant est de d�clarer comme attribut dans la classe WidgetItem un pointeur de fonction.

    On obtient alors en C++:
    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
    class WidgetItem {
        public:
            ...
            void set_action(void (*f)(void)) {
                function = f;
            }
     
            void action() {
                function();
            }
     
            private:
                void (*function)(void);
    };
    ...
    void do_something() {
        printf("Action");
    }
    ...
    void do_something_else() {
        printf("Another Action");
    }
     ...
    // dans le main
    WidgetItem i();
    i.set_action(do_something);
    i.action();        // Affiche sur le terminal  "Action"
    i.set_action(do_something_else);
    i.action();       // Affiche sur le terminal "Another Action"
    Cette m�thode arrive vite � ses limites lorsque l'action � r�aliser doit avoir acc�s aux membres d'autres objets..

    Je suis � l'�coute de toutes vos solutions aussi "bidoullage" soient-elles .
    Merci d'avance !

  2. #2
    Expert confirm�

    Homme Profil pro
    Ing�nieur syst�mes et r�seaux
    Inscrit en
    F�vrier 2007
    Messages
    4 253
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Ing�nieur syst�mes et r�seaux
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par d�faut
    Mais c'est l� qu'il y a erreur de "conception"...
    C'est pas le widget qui doit r�agir au click... mais un objet qui doit r�agir au click sur le widget.... (ce qui, au passage, te simpliefiera grandement la vie quand tu devras "rejouer" quelque chose sans widget).

    La derni�re fois que j'avais jou� avec un framework (mais ca remonte � un paquet d'ann�es... genre 12/13) de GUI, on �tait arriv� � la conclusion suivante (qui, �tonnemment ou non, est la mani�re dont la plupart des OS fonctionnent).
    Quand un widget(item) doit g�n�rer un evenement, il genere cet evenement... genre "user clicked on me"...
    Ensuite cet evenement "remonte" la liste des widgets jusqu'� disparaitre si personne ne se sert de l'�venement.

    La classe widget de base a donc un pointeur sur le widget parent (pour redispatcher le message), et surtout:
    - Une map<eventid,vector<listener*>>

    Quand un event est dispatch� par le wiget:
    1. Il regarde si il existe une liste de listener associ� par � cet event.
    2. Pour chaque listener dans cette liste il appelle une fonction "handleEvent(event)" jusqu'� que l'un de ces listener lui dise: "STOP, je catch le truc".
    3. Si aucun listener n'a "catch�" l'�venement, alors il appele le "handleEvent" de son parent (et oui, un widget est un listener), qui, par d�faut, va dispatcher l'event � son tour.

    Windows rajoute des fioritures, par exemple: est ce que l'evenement doit remonter au parent... (peut �tre interessant pour g�rer un ascenseur qui est un widget avec 5 sous widgets et qui doit piloter le widget parent )

    Un truc genre (pseudocode):
    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
     
    interface EventListener
    {
         virtual bool handleEvent(const Event& evt) = 0;
    };
     
    class Widget : public EventListener
    {
        Widget* pParent;
        bool bBroadcastToParent;
        Map<int,Vector<EventListener*>>  listeners;
     
        public:
           virtual bool handleEvent(const Event& evt) {
               bool catched = dispathEvent(evt);
               if (!catched && bBroadcastToParent && pParent) 
                            catched = pParent->handleEvent() :
               return catched;
           }
     
       protected:
           virtual bool dispatchEvent(const Event& evt) {
                 ...
            }
    };

  3. #3
    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 : 51
    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
    Par d�faut
    Pour d�finir ce genre de chose en C++, on utilisera g�n�ralement des foncteurs (voire boost::function et boost::bind, par exemple), mieux encore, on les mettra avec un syst�me de signaux/slots (il y a un truc comme �a dans Qt par exemple, et boost::signal en fourni une version portable).

    Dans le futur, le C++ fournira des fonction lambda pour aider (entre autre) � d�finir le contenu des slots.
    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.

  4. #4
    Membre r�gulier
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Septembre 2008
    Messages
    9
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 38
    Localisation : France, Alpes Maritimes (Provence Alpes C�te d'Azur)

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Par d�faut

    Je vais pousser mon analyse dans ces voies l�. La 1ere solution des �couteurs est adopt�e dans SWING pour Java. Un petit coup d'oeil � la Javadoc et on adapte �a en C++. C'est peut �tre aussi l'occasion de se lancer dans l'apprentissage de Boost, le systeme de signal&slot � la Qt est assez int�ressant.

    Nicroman une question: pour chaque widget de l'ensemble du programme faut-il d�finir un event_id? N'y-a-t-il pas de m�thode plus g�n�rique car � chaque ajout de widget, il faut d�finir une nouvelle constante ? (Dans un jeu typiquement RPG, il y a un nombre consid�rable de menus, tableaux, boutons et etc). Merci !

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. classe interne anonyme
    Par oliveettom dans le forum Langage
    R�ponses: 1
    Dernier message: 09/05/2013, 00h25
  2. Red�finir un constructeur dans une classe interne anonyme
    Par pigpen dans le forum D�buter avec Java
    R�ponses: 3
    Dernier message: 31/10/2011, 13h36
  3. R�ponses: 5
    Dernier message: 19/07/2009, 19h20
  4. R�ponses: 3
    Dernier message: 09/04/2008, 11h24
  5. Classe anonyme et classe interne
    Par amazircool dans le forum Langage
    R�ponses: 8
    Dernier message: 26/12/2007, 14h45

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