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 :

Reflexion en C++


Sujet :

C++

  1. #21
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par Médinoc
    Donc, ce que tu cherches à faire, c'est de la conversion d'appel ?
    Créer un appel de toutes pièces à partir de données extérieures, et les appeler ?
    J'ai pas bien compris. En fait ce ke je veux c'est ca: etant donné un objet que je viens de construire, et etant donné le nom d'une de ses methodes en string, bainh tous simplement comment l'appeler????

    Apres viennet les cas les plus delicats qui sont: c'est quand j ai plusieurs objets, et que j'ai un nom de methodes mais avec plusieurs signature) donc apparament là, il faut savoir quelle methode appliquer et surtout sur quel objet???? mais pour le moment occupons nous du premier cas plus simple où on a qu'un seule methode (non surchargée et sans parametre) et un seul objet o.

  2. #22
    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 518
    Points
    41 518
    Par défaut
    Pour le cas simple: typedef de pointeur de fonction membre pour la classe mère ancestrale, + une map...
    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.

  3. #23
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Voici un exemple de map de pointeur de fonction:
    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
    #include <iostream>
    #include <string>
    #include <map>
     
    using namespace std;
     
    typedef int (*FonctionSansArgument)();
     
    std::map<std::string, FonctionSansArgument> mymap;
     
    int FonctionSansArgument1()
    {
    	return 1;
    }
     
    int FonctionSansArgument2()
    {
    	return 2;
    }
     
    int FonctionSansArgument3()
    {
    	return 3;
    }
     
    int main(int argc, char* argv[])
    {
    	//construction de la map
    	mymap["FonctionSansArgument1"] = FonctionSansArgument1;
    	mymap["FonctionSansArgument2"] = FonctionSansArgument2;
    	mymap["FonctionSansArgument3"] = FonctionSansArgument3;
     
    	// utilisation de la map
    	cout << (*mymap["FonctionSansArgument1"])() << endl;
    	cout << (*mymap["FonctionSansArgument2"])() << endl;
    	cout << (*mymap["FonctionSansArgument3"])() << endl;
     
    	cin.get();
    	return 0;
    }
    J'ai fais ça rapido. Ca fonctionne, mais ça doit pouvoir être amélioré. C'est juste pour faire comprendre le principe.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  4. #24
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par Médinoc
    Pour le cas simple: typedef de pointeur de fonction membre pour la classe mère ancestrale, + une map...
    avec ta proposistion, si kelkun ajoute une autre methode a la classe, et qu'il envoi le nom de cette methode en tant que chaine de caractere il doit voir l'executer alors que non car il fallait redefinir un autre typedef avec le nouveau type de fonction ainsi crée et le mettre dans mon map. moi plutot ce que je veux avoir c'est sans devoir etre obligé de creer des typdef autant que de methodes que j'ai... c'est un peu louche mais ce sont mes spec

    En fait ce truc c est tres faisable en C# et meme tres vite fait car c est du C# natif cad sans avoir besoin d'un projet qui fé ca

  5. #25
    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 518
    Points
    41 518
    Par défaut
    Ben, non, un seul typedef...
    Exemple pour le cas simple : Tout ce qu'il faut changer, c'est la map :
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    class CClasseMere
    {
    };
     
    class CUneClasseFille : public CClasseMere
    {
    public:
    	int UneFonction(void);
    	int UneAutreFonction(void);
    };
     
    class CUneAutreClasseFille : public CClasseMere
    {
    public:
    	int EncoreUneAutreFonction(void);
    };
     
    typedef int (CClasseMere::* PTR_FONC_VOID)(void);
     
    void TestPtrFonc(void)
    {
    	std::map<std::string, PTR_FONC_VOID> mapReflexion;
    	//Note: Le static_cast est nécessaire car il y a un upcast dans l'opération.
    	//Mais ça ne marche qu'avec un static_cast : Si un cast moins restrictif est nécessaire, ça plantera à l'exécution.
    	mapReflexion[ "CUneClasseFille::UneFonction" ] = static_cast< PTR_FONC_VOID >(&CUneClasseFille::UneFonction);
    	mapReflexion[ "CUneClasseFille::UneAutreFonction" ] = static_cast< PTR_FONC_VOID >(&CUneClasseFille::UneAutreFonction);
    	mapReflexion[ "CUneAutreClasseFille::EncoreUneAutreFonction" ] = static_cast< PTR_FONC_VOID >(&CUneAutreClasseFille::EncoreUneAutreFonction);
     
    	//Consultation
    	PTR_FONC_VOID fonc = mapReflexion[ "CUneClasseFille::UneAutreFonction" ];
    	CUneClasseFille objetFille;
    	int resultat = (objetFille.*fonc)();
    }
    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.

  6. #26
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par bouzaidi
    En fait ce truc c est tres faisable en C# et meme tres vite fait car c est du C# natif cad sans avoir besoin d'un projet qui fé ca
    Bah oui, mais le C# c'est interprété et c'est trés lent. Chaque langage a ses avantages et ses inconvénients, et un des désavantages du c++ est qu'il ne fait pas de réflexion.
    Bon, par contre, il y a bien cette histoire de RTTI, mais je ne connais pas. Je crois que c'est juste pour récupérer les types des objets.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  7. #27
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    pour récupérer le type d'un objet:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class PunchingBall
    {
      public:
        ...
    };
     
    int main()
    {
      PunchingBall speedy;
     
      std::cout << typeid(speedy) << std::endl; // "PunchingBall"
    }
    D'ailleurs c'est du C (le typeid). C'est vrai que c'est bizarre qu'on puisse avoir le nom d'une classe même quand c'est compilé.

  8. #28
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    Medinoc, J'avoue que ta methode est tres suffisante dans le cas simple. Maintenant sur ton exemple si on ajoute dans les classe CUneClasseFille et CUneAutreClasseFille deux autres methodes mais pas de meme type PTR_FONC_VOID (on suppose que cette fois ci elles retournent une valeur double) alors lààà par contre il faudra recréer un autre typedef et un autre map N'est ce pas???

  9. #29
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 58
    Points : 66
    Points
    66
    Par défaut
    sinon, tu peux faire un truc dans ce genre la (mais c'est un peu codé a la roots):

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
     
     
    template <class Object>
    class CMetaObject
    {
     
    public:
     
    	virtual ~CMetaObject()
    	{
    	}
     
    	class IMetaMethod
    	{
    	public:
    		virtual string Call(Object *_pkObject,string *_apsArgs)=0;
    	};
     
    	template <class Return>
    	class CMetaMethod0 : public IMetaMethod
    	{
    	public:
    		typedef Return (Object::*tMeth)();
    		CMetaMethod0(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual string Call(Object *_pkObject,string *_apsArgs)
    		{
    			(_pkObject->*m_fMethod)();
    			return("");
    		}
    		tMeth m_fMethod;
    	};
     
    	template <class Return,class P1>
    	class CMetaMethod1 : public IMetaMethod
    	{
    	public:
    		typedef Return (Object::*tMeth)(P1);
    		CMetaMethod1(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual string Call(Object *_pkObject,string *_apsArgs)
    		{
    			(_pkObject->*m_fMethod)(boost::lexical_cast<P1>(_apsArgs[0]));
    			return("");
    		}
    		tMeth m_fMethod;
    	};
     
    	template <class Return,class P1,class P2>
    	class CMetaMethod2 : public IMetaMethod
    	{
    	public:
    		typedef Return (Object::*tMeth)(P1,P2);
    		CMetaMethod2(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual string Call(Object *_pkObject,string *_apsArgs)
    		{
    			(_pkObject->*m_fMethod)(boost::lexical_cast<P1>(_apsArgs[0]),boost::lexical_cast<P2>(_apsArgs[1]));
    			return("");
    		}
    		tMeth m_fMethod;
    	};
     
    	class Desc
    	{
    	public:
    		void Register(const string &_sName,IMetaMethod *_pkMethod)
    		{
    			m_kMethods[_sName]=_pkMethod;
    		}
    		map<string,IMetaMethod*> m_kMethods;
    	};
     
    	static Desc &GetDesc()
    	{
    		static Desc kDesc;
    		return(kDesc);
    	}
     
    	string MetaCall(const string &_sMethod)
    	{
    		return(GetDesc().m_kMethods[_sMethod]->Call(dynamic_cast<Object*>(this),NULL));
    	}
     
    	string MetaCall(const string &_sMethod,const string &_sArg1)
    	{
    		string asArgs[]={_sArg1};
    		return(GetDesc().m_kMethods[_sMethod]->Call(dynamic_cast<Object*>(this),asArgs));
    	}
     
    	string MetaCall(const string &_sMethod,const string &_sArg1,const string &_sArg2)
    	{
    		string asArgs[]={_sArg1,_sArg2};
    		return(GetDesc().m_kMethods[_sMethod]->Call(dynamic_cast<Object*>(this),asArgs));
    	}
     
    };
     
    class CTest : public CMetaObject<CTest>
    {
     
    public:
     
    	void Pipo(int _iValue)
    	{
    	}
     
    	void Mito(string _s1,string _s2)
    	{
    	}
     
    	static void InitMetaClass()
    	{
    		GetDesc().Register("pipo",new CMetaMethod1<void,int>(&CTest::Pipo));
    		GetDesc().Register("mito",new CMetaMethod2<void,string,string>(&CTest::Mito));
    	}
     
    };
     
    int Main()
    {
    	CTest::InitMetaClass();
     
    	CTest kTest;
    	kTest.MetaCall("pipo","1");
    	kTest.MetaCall("mito","hello","world");
    }

  10. #30
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    Medinoc, Si on pourrait juste mettre dans ton MAP des pointeurs sur tous type de fonction ca serait un truc qui me suffiras largement pour mon truc.

    Sinon pour la classe CMetaObject je suis en train de la voir j'espere qu'elle me repondra le plus a mes besoin. Merci

  11. #31
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    Merci PierroElMito, Apparament ta solution me conviendra tres bien. Sinon je voudrais bien que tu m'expliquerais juste si je veu ajouter une classe CMetaMethod3 pour decrire le type des fonction qui ont par exemple un parametre char* qui va etre remplie apres apres l'appel de la methode ou bien le type d'une fonction qui renvoi un double en retour par exemple. Bref: le truc de retour n'est pas traité dans ton exemple, et j'aimerais bien avoir un exemple comme cela

    dans le cas de type de fonction qui retourne un double par exemple ce n'est pas un probleme car on ecrira a la fin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int Main()
    {
    	CTest::InitMetaClass();
     
    	CTest kTest;
    	double d;
                 d = kTest.MetaCall("pipo","1"); //cad que pipo renvoi un double et plus void
                 //sinon si pipo ne renvoi rien en retour mais a un parametre char *c qui va etre remplit apres l'appele comment ferais je alors???
    }
    Merci par avance

  12. #32
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 58
    Points : 66
    Points
    66
    Par défaut
    en fait, les types des parametres sont décris au "Register" de la méthode. comme ça passe par un boost::lexical_cast, je crois pas qu'on puisse ajouter des méthodes avec des char *. je vérifierai ça demain, ce soir je peux pas.
    pour les params de retour, il faudrait faire un truc dans ce style là:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	template <class RetType>
    	RetType MetaCall(const string &_sMethod,const string &_sArg1,const string &_sArg2)
    	{
    		string asArgs[]={_sArg1,_sArg2};
    		return(boost::lexical_cast<RetType>(GetDesc().m_kMethods[_sMethod]->Call(dynamic_cast<Object*>(this),asArgs)));
    	}
    mais j'avoue que dans mon exemple, je pensais plutot renvoyer des chaines de caractères. sinon, si tu veux utiliser cette solution, il faudra un peu blinder le code, parce qu'actuellement, la moindre erreur provoquera un plantage

  13. #33
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    Merci infinment pour ton aide.
    En fait je n'ai pas le choix, et je ne peux changer les signature des methodes qui ont un parametre char* car là où je fais mon stage on a un logiciel avec juste les fichiers .h et non les .cpp du coup je peux changer le code et malheureusement y a plein de methodes que je doi utiliser et qui ont un char* comme parametre

  14. #34
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 58
    Points : 66
    Points
    66
    Par défaut
    pour gérer les type de retour, il y a moyen de faire comme ça, mais bon, c'est pas terrible, parce que ça fait dupliquer du code pour pas grand chose...
    sinon, j'ai enlevé les parametres en 'string', parce que c'etait pas top non plus.
    par contre, l'utilisation des paramètres en 'char *', ça marche vraiment pas.

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
     
    template <class Object>
    class CMetaObject
    {
     
    public:
     
    	virtual ~CMetaObject()
    	{
    	}
     
    	class IMetaMethod
    	{
    	public:
    		virtual boost::any Call(Object *_pkObject,boost::any *_apsArgs)=0;
    	};
     
    	template <class Return>
    	class CMetaMethod0 : public IMetaMethod
    	{
    	public:
    		typedef Return (Object::*tMeth)();
    		CMetaMethod0(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual boost::any Call(Object *_pkObject,boost::any *_apsArgs)
    		{
    			return((_pkObject->*m_fMethod)());
    		}
    		tMeth m_fMethod;
    	};
     
    	template <>
    	class CMetaMethod0<void> : public IMetaMethod
    	{
    	public:
    		typedef void (Object::*tMeth)();
    		CMetaMethod0(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual boost::any Call(Object *_pkObject,boost::any *_apsArgs)
    		{
    			(_pkObject->*m_fMethod)();
    			return(0);
    		}
    		tMeth m_fMethod;
    	};
     
    	template <class Return,class P1>
    	class CMetaMethod1 : public IMetaMethod
    	{
    	public:
    		typedef Return (Object::*tMeth)(P1);
    		CMetaMethod1(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual boost::any Call(Object *_pkObject,boost::any *_apsArgs)
    		{
    			return((_pkObject->*m_fMethod)(boost::any_cast<P1>(_apsArgs[0])));
    		}
    		tMeth m_fMethod;
    	};
     
    	template <class P1>
    	class CMetaMethod1<void,P1> : public IMetaMethod
    	{
    	public:
    		typedef void (Object::*tMeth)(P1);
    		CMetaMethod1(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual boost::any Call(Object *_pkObject,boost::any *_apsArgs)
    		{
    			(_pkObject->*m_fMethod)(boost::any_cast<P1>(_apsArgs[0]));
    			return(0);
    		}
    		tMeth m_fMethod;
    	};
     
    	template <class Return,class P1,class P2>
    	class CMetaMethod2 : public IMetaMethod
    	{
    	public:
    		typedef Return (Object::*tMeth)(P1,P2);
    		CMetaMethod2(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual boost::any Call(Object *_pkObject,boost::any *_apsArgs)
    		{
    			return((_pkObject->*m_fMethod)(boost::any_cast<P1>(_apsArgs[0]),boost::any_cast<P2>(_apsArgs[1])));
    		}
    		tMeth m_fMethod;
    	};
     
    	template <class P1,class P2>
    	class CMetaMethod2<void,P1,P2> : public IMetaMethod
    	{
    	public:
    		typedef void (Object::*tMeth)(P1,P2);
    		CMetaMethod2(const tMeth &_fMethod):
    			m_fMethod(_fMethod)
    		{
    		}
    		virtual boost::any Call(Object *_pkObject,boost::any *_apsArgs)
    		{
    			(_pkObject->*m_fMethod)(boost::any_cast<P1>(_apsArgs[0]),boost::any_cast<P2>(_apsArgs[1]));
    			return(0);
    		}
    		tMeth m_fMethod;
    	};
     
    	class Desc
    	{
    	public:
    		void Register(const string &_sName,IMetaMethod *_pkMethod)
    		{
    			m_kMethods[_sName]=_pkMethod;
    		}
    		map<string,IMetaMethod*> m_kMethods;
    	};
     
    	static Desc &GetDesc()
    	{
    		static Desc kDesc;
    		return(kDesc);
    	}
     
    	template <class TypeResult>
    	void AssignNonVoid(TypeResult *_pkResult,const boost::any &_kValue)
    	{
    		*_pkResult=boost::any_cast<TypeResult>(_kValue);
    	}
     
    	template <>
    	void AssignNonVoid<void>(void *_pkResult,const boost::any &_kValue)
    	{
    	}
     
    	template <class TypeResult>
    	void MetaCall(const string &_sMethod,TypeResult *_pkResult=NULL)
    	{
    		boost::any kResult=GetDesc().m_kMethods[_sMethod]->Call(dynamic_cast<Object*>(this),NULL);
    		if (_pkResult)
    			AssignNonVoid<TypeResult>(_pkResult,kResult);
    	}
     
    	template <class TypeResult>
    	void MetaCall(const string &_sMethod,const boost::any &_kArg1,TypeResult *_pkResult=NULL)
    	{
    		boost::any asArgs[]={_kArg1};
    		boost::any kResult=GetDesc().m_kMethods[_sMethod]->Call(dynamic_cast<Object*>(this),asArgs);
    		if (_pkResult)
    			AssignNonVoid<TypeResult>(_pkResult,kResult);
    	}
     
    	template <class TypeResult>
    	void MetaCall(const string &_sMethod,const boost::any &_kArg1,const boost::any &_kArg2,TypeResult *_pkResult=NULL)
    	{
    		boost::any asArgs[]={_kArg1,_kArg2};
    		boost::any kResult=GetDesc().m_kMethods[_sMethod]->Call(dynamic_cast<Object*>(this),asArgs);
    		if (_pkResult)
    			AssignNonVoid<TypeResult>(_pkResult,kResult);
    	}
     
    };
     
    class CTest : public CMetaObject<CTest>
    {
     
    public:
     
    	void Pipo(int _iValue)
    	{
    	}
     
    	float Mito(const string &_s1,const string &_s2)
    	{
    		return(1.23456f);
    	}
     
    	void TestCharPtr(const char *_sz)
    	{
    	}
     
    	static void InitMetaClass()
    	{
    		GetDesc().Register("pipo",new CMetaMethod1<void,int>(&CTest::Pipo));
    		GetDesc().Register("mito",new CMetaMethod2<float,const string &,const string &>(&CTest::Mito));
    		//GetDesc().Register("testcharptr",new CMetaMethod1<void,const char *>(&CTest::TestCharPtr));
    	}
     
    };
     
    int Main()
    {
    	CTest::InitMetaClass();
     
    	CTest kTest;
    	kTest.MetaCall<void>("pipo",1);
    	float fR;
    	kTest.MetaCall<float>("mito",string("hello"),string("world"),&fR);
    	//kTest.MetaCall<void>("testcharptr","yep!");
    }

  15. #35
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    J'ai essayé de compiler ton code mais il me renvoi 3 erreurs car je ne sais comment incluer boost (l'erreur di boost is not a class or namespace name). comment faire pour incluer boost STP

  16. #36
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 58
    Points : 66
    Points
    66
    Par défaut
    c'est une librairie externe:
    http://www.boost.org/
    il faut la télécharger ici:
    http://sourceforge.net/project/showf...?group_id=7586

  17. #37
    Membre à l'essai
    Inscrit en
    Juin 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2007
    Messages : 33
    Points : 22
    Points
    22
    Par défaut
    Et y aurait-il une facon de faire pour récupérer l'adresse d'une fonction à partir de son nom, ca pourrait etre un début ?

  18. #38
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    Par défaut
    sous windows getprocadress(...) ... il existe un equivalent linux

  19. #39
    Membre à l'essai
    Inscrit en
    Juin 2007
    Messages
    33
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juin 2007
    Messages : 33
    Points : 22
    Points
    22
    Par défaut
    Une discussion entre collègues à midi a fait emergé une autre idée.
    Si on ecrivait les fonctions dans un fichier que l'on execute ensuite?
    Ca se fait non ?
    Ds ce cas comment pourrait-on lancer l'execution d'un tel fichier?

  20. #40
    Membre du Club
    Inscrit en
    Avril 2007
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 187
    Points : 55
    Points
    55
    Par défaut
    Xorgnem: Jai pensé a ce truc de faire les nom des fonctions dans un fichier mais je sias pas comment faire pour appeler les fonction... Je crois que l'XML a un rapport non?

Discussions similaires

  1. [VB.NET]Reflexion lister les membres d'une classe ...presque
    Par lucie.houel dans le forum ASP.NET
    Réponses: 19
    Dernier message: 20/09/2005, 14h49
  2. [débat] Reflexion sur « quel langage ?»
    Par jack69 dans le forum Langages de programmation
    Réponses: 8
    Dernier message: 23/05/2005, 09h30

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