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 :

Appel fonction via un string


Sujet :

C++

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 38
    Points : 46
    Points
    46
    Par défaut Appel fonction via un string
    Salut,

    Est ce qu'il est possible d'appeller une fonction via le nom de cette fonction (string). Je m'explique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int toto() {
     
    }
     
    int main() {
        string t = "toto()";
        //pouvoir appeller la fonction via ce string
    }
    Merci pour les réponses....

  2. #2
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    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 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Non.
    C'est à toi d'associer tes chaines à des fonctions (boost::bind et boost::function peuvent être une piste de réponse). Si en plus tu dois passer des arguments, cela devient encore plus compliqué.

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 38
    Points : 46
    Points
    46
    Par défaut
    Oki merci je vais aller voir du côté de ses fonctions (bind et fonction).

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    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
    #include <iostream>
    #include <map>
     
    void toto()
    {
         std::cout << "Je suis la fonction toto" << std::endl;
    }
     
    int main()
    {
        std::map<std::string, void(*)()> map;
        map["toto"] = &toto;
     
        map["toto"]();
    }

  5. #5
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 37
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par loufoque
    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
    #include <iostream>
    #include <map>
     
    void toto()
    {
         std::cout << "Je suis la fonction toto" << std::endl;
    }
     
    int main()
    {
        std::map<std::string, void(*)()> map;
        map["toto"] = &toto;
     
        map["toto"]();
    }
    Salut,

    Je souhaiterais utiliser cette méthode, mais pas avec des fonction, plutôt avec des constructeurs. Par contre, je ne vois pas comment m'y prendre. Cela est il possible?

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 380
    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 380
    Points : 41 576
    Points
    41 576
    Par défaut
    Pour des constructeurs, renseigne-toi sur le pattern "factory".

  7. #7
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 37
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par Médinoc
    Pour des constructeurs, renseigne-toi sur le pattern "factory".


    Je récupère une chaine de caractères depuis un parser, et suivant la chaine en question, je veux créer l'objet qui lui correspond.
    Je ne comprends pas commment le pattern factory peut m'aider dans ce cas. Tu pourrais m'éclairer ?

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Je souhaiterais utiliser cette méthode, mais pas avec des fonction, plutôt avec des constructeurs. Par contre, je ne vois pas comment m'y prendre. Cela est il possible?
    Si tu veux uniquement stocker les constructeurs par défaut, peut-être.
    Je sais pas si on peut avoir un pointeur vers un constructeur par contre.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 380
    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 380
    Points : 41 576
    Points
    41 576
    Par défaut
    Le pattern factory, ça peut être un ensemble de pointeurs vers des fonctions qui font juste un new...

    Un petit 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
    26
    27
    28
    29
    30
    31
    class CClasseDeBaseObjetDynamique;
    class CUneClasse : public CClasseDeBaseObjetDynamique;
    class CUneAutreClasse : public CClasseDeBaseObjetDynamique;
     
    CClasseDeBaseObjetDynamique * CreerObjetDUneClasse(void)
    {
       return new CUneClasse;
    }
     
    CClasseDeBaseObjetDynamique * CreerObjetDUneAutreClasse(void)
    {
       return new CUneAutreClasse;
    }
     
    typedef CClasseDeBaseObjetDynamique (*FonctionCreatrice)(void)
    map< string, FonctionCreatrice > g_fonctions;
     
    void Initialiser(void)
    {
       g_fonctions["UneClasse"] = CreerObjetDUneClasse;
       g_fonctions["UneAutreClasse"] = CreerObjetDUneAutreClasse;
    }
     
    CClasseDeBaseObjetDynamique * CreeObjet(string nomClasse)
    {
       FonctionCreatrice fonc = g_fonctions[nomClasse];
       if( fonc==NULL )
          return NULL;
       CClasseDeBaseObjetDynamique * obj = fonc();
       return obj;
    }

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    On peut faire plus générique, plus simple, et sans utiliser new (qui impose allocation dynamique).

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 380
    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 380
    Points : 41 576
    Points
    41 576
    Par défaut
    OK, je laisse faire le maître.
    Montre ta méthode.

  12. #12
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    On peut essayer de faire un truc similaire à boost::function.

    J'ai aussi écrit ça vite fait sans tester, y'a peut-être des erreurs.
    Et puis l'interface peut aussi être améliorée.

    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
    namespace detail
    {
         template<typename T>
         void ctor_apply(void* p)
         {
              new(p) T;
         }
    }
     
    // un simple indicateur
    template<typename T>
    struct constructor_type
    {
    };
     
    class constructor
    {
        template<typename T>
        constructor(constructor_type<T>)
        {
            ctor_ = &detail::ctor_apply<T>;
        }
     
        template<typename T>
        constructor& operator=(constructor_type<T>)
        {
            ctor_ = &detail::ctor_apply<T>;
        }
     
        constructor& operator=(const constructor &c)
        {
             ctor_ = c.ctor_;
        }
     
        void apply(void *p)
        {
            ctor_(p);
        }
     
    private:
        void (*ctor_)(void*);
    };
    un constructor peut alors contenir le constructeur par défaut de n'importe quel type.

    Avec une technique similaire et si on disposait des fonctions virtuelles templates, on pourrait même appeler un constructeur prenant n'importe quel nombre de paramètres.

  13. #13
    Membre à l'essai
    Inscrit en
    Janvier 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 37
    Points : 20
    Points
    20
    Par défaut
    Je vous remercie pour vos réponses, j'ai pour l'instant codé la méthode qui utilise la factory.

    Loufoque ( ou quelqu'un d'autre, après tout ), pourrais tu me donner un petit exemple d'tulisation de ton code, car j'ai un peu de mal à suivre mais je voudrais bien comprendre.

  14. #14
    Membre averti
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Points : 307
    Points
    307
    Par défaut
    Citation Envoyé par loufoque

    [code]namespace detail
    {
    template<typename T>
    void ctor_apply(void* p)
    {
    new(p) T;
    }
    }
    Cool la méthode.

    Mais j'ai quand même deux questions (points pas clair pour moi encore)
    :
    1. Le placement new ne poserait pas problème dans le cas d'un héritage avec des enfants de taille supérieure ?

    2. Je ne vois pas trop comment utiliser ta méthode avec des classes virtuelles (on aurait plus tendance à vouloir récupérer un pointeur sur l'objet créé).

  15. #15
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    L'idée de constructor est d'avoir une variable qui peut "contenir" le constructeur par défaut de n'importe quel type.
    Tu l'informes du type à contenir en utilisant constructor_type.

    Tu construis alors ton objet en fournissant à la fonction apply une adresse vers un emplacement mémoire suffisamment grand et avec un alignement compatible avec les objets de type que tu veux créer.
    Malheureusement c'est vrai qu'en fait il aurait été pas mal que ce soit constructor qui se charge d'allouer l'objet, parce que sinon on ne connait pas le type, et donc pas la taille, de l'objet à allouer.

    Peut-être qu'utiliser une interface d'allocateurs permettrait une meilleure souplesse, pour pouvoir exploiter le cas où l'on connait la taille.

    Mais comment alors libérer l'objet créé ? En rajoutant un second pointeur de fonction vers une fonction qui appelle delete par exemple. (On plutôt, pour optimiser la taille, en ayant un pointeur vers une classe polymorphe qui contiendrait ces deux fonctions)

    Mais si on suit le RAII, alors l'objet doit être responsable de la destruction des objets qu'il créé. Ce qui signifie alors que l'objet doit être contenu. Donc du coup, ça revient à coder boost.any.

    Ou alors on se restreint au polymorphisme et à new/delete et on retourne des shared_ptr.
    Ce qui correspond mieux à l'idée du Design Pattern Factory.

  16. #16
    Membre averti
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Points : 307
    Points
    307
    Par défaut
    La solution par allocator me semble trop théorique.

    Citation Envoyé par loufoque
    Mais si on suit le RAII, alors l'objet doit être responsable de la destruction des objets qu'il créé. Ce qui signifie alors que l'objet doit être contenu. Donc du coup, ça revient à coder boost.any.

    Ou alors on se restreint au polymorphisme et à new/delete et on retourne des shared_ptr.
    Ce qui correspond mieux à l'idée du Design Pattern Factory.
    Un simple auto_ptr suffirait pour expliciter le passage de responsibilité sur la désallocation.

  17. #17
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Faire un delete sur un type différent de celui utilisé lors du new correspondant est un comportement indéfini.
    À part si le type est une base de celui utilisé lors du new et si le destructeur est virtuel.

    D'où la simplicité gagnée en se restreignant au polymorphisme et à new/delete.
    (Cette fonctionnalité n'est pas possible avec les allocateurs, il faut absolument que le type utilisé pour la désallocation soit le même que pour l'allocation)

  18. #18
    Membre averti
    Avatar de David Fleury
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    253
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 253
    Points : 307
    Points
    307
    Par défaut
    Je me demande si je n'ai pas déjà vu une implémentation de ta proposition par allocator dans le livre d'Alexandrescu Modern C++ Design, où il met en place une farbrique de ce style. (peut être est-elle dispo dans loki)

Discussions similaires

  1. Appeler fonction via un formulaire
    Par Shivas dans le forum Langage
    Réponses: 10
    Dernier message: 10/07/2009, 13h20
  2. [DOM] appeler une fonction via son nom (qui est une string)
    Par elekis dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 15/07/2008, 13h06
  3. Appel Fonction PERL via KSH
    Par mego dans le forum Langage
    Réponses: 2
    Dernier message: 25/02/2007, 13h06
  4. Réponses: 8
    Dernier message: 13/08/2004, 12h32
  5. appel xmlservice via fonction javascript
    Par pram dans le forum XMLRAD
    Réponses: 2
    Dernier message: 06/05/2003, 14h24

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