Templates et pointeurs de fonctions membres?

Templates et pointeurs de fonctions membres? - C++ - Programmation

Marsh Posté le 08-11-2004 à 23:17:05    

Salut tout le monde;
 
Je me demandais si les templates pouvaient recevoir comme type des pointeurs de fonctions membres?
Si c'est le cas je ne comprend pas pourquoi ceci ne marche pas :
 
J'essaye en fait de donner un pointeur de fonction membre d'un objet quelconque à un ActionListener pour pouvoir ensuite donner à un controller des pointeurs de fonctions membres d'ActionListener
J'ai cru en être obligé de faire ça du fait que les types de fonctions membres d'objets différents sont incompatibles.
 
(si existe des types de pointeur de fonction membres d’objet « void » ça m’intéresse aussi  :D )
 
J'improvise c'est peu êter pas comme ça qu'il faut qu'il faut s'y prendre pour implémenter un controller mais bon si ce problème est résolut ça devrai marcher.
 

Code :
  1. //pointeurs de fonction membre de test
  2. typedef void (Test::*ptr_TestFunc) (int, int, int);
  3. //...
  4. //pointeur de fonction membre d'ActionListener
  5. template<class ptrMethode>
  6. typedef void (ActionListener<ptrMethode>::*ptr_ActionListenerFunc) (int, int, int);
  7. //Class ActionListener
  8. template<class ptrMethode>
  9. class ActionListener{
  10. ActionType type;
  11. ptrMethode action;
  12. public:
  13.         //constructeur
  14. ActionListener(ActionType _type, ptrMethode _action): type(_type), action(_action){}
  15. void actionPerformed(int key, int x, int y) { cout<<"Call methode"<<endl; action(key, x, y)}
  16. };
  17. //....
  18. //le problème se pose ici
  19. button1->addActionListener(new ActionListener<ptr_TestFunc>(KeyEvent, buttonKeyEventActionPreformed));


error C2440: 'initializing' : cannot convert from 'class ActionListener<void (__thiscall Test::*)(int,int,int)> *' to 'class ActionListener<ptrMethode> *'
 
Ce qui m'inquiète c'est que dans le message d'erreur le template est pas interprété.
 
Si vous avez des conseil, avis ils sont les bienvenu...
 :bounce:


Message édité par peak le 08-11-2004 à 23:18:18
Reply

Marsh Posté le 08-11-2004 à 23:17:05   

Reply

Marsh Posté le 08-11-2004 à 23:29:32    

et si tu nous donnais le code de ta classe composant (methode addActionListener) ?


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 08-11-2004 à 23:55:48    

oui, désolé,
 

Code :
  1. template<class ptrMethode>
  2. typedef ActionListener<ptrMethode> *ptr_ActionListener;
  3. //...
  4. void Component::addActionListener(ptr_ActionListener p_action_list){
  5. cout<<"Component::addActionListener"<<endl;
  6. }


Message édité par peak le 08-11-2004 à 23:56:09
Reply

Marsh Posté le 09-11-2004 à 00:00:50    

moi je comprends pas ce que tu fais, ni où est le problème. Alors je te dirais tout simplement de tout virer.
 
Fais une classe template<typename Functor>
un membre Functor initialisé dans le constructeur
dans ta actionPerformed, tu fais un gros this->func(a, b, c)
 
et tu rajoutes un sucre syntaxique : une fonction qui crée les instances pour faire marcher la déduction de type

Reply

Marsh Posté le 09-11-2004 à 00:02:12    

new ActionListener<ptr_TestFunc>(KeyEvent, buttonKeyEventActionPreformed
 
je vois pas comment ton truc ça peut marche, les différentes instances template d'ActionListener n'ont aucun lien de parenté, à part void*, tu peux rien en faire

Reply

Marsh Posté le 09-11-2004 à 00:08:42    

ok, cool, en fait c'est plus ou moins ce que j'avais voulu faire.
Et ça m'arrange bien que tu me dises que y'ai moyen par ce que je commençais à me dire que je voyais vraiment pas comment faire autrement.
 
 
Mais donc ici dans mon ActionListener je devrai pouvoir chopper un pointeur de fonction membre de test, donc je capte pas pourquoi ça passe pas!
 
En fait c'est l'initialisation d'ActionListener qui plante:

Code :
  1. new ActionListener<ptr_TestFunc>(KeyEvent, buttonKeyEventActionPreformed)

Reply

Marsh Posté le 09-11-2004 à 00:11:20    

ha merde je viens de voir le message au dessus  :ange:


Message édité par peak le 09-11-2004 à 00:11:33
Reply

Marsh Posté le 09-11-2004 à 00:17:14    

Taz a écrit :

les différentes instances template d'ActionListener n'ont aucun lien de parenté, à part void*, tu peux rien en faire


 
Ben j'ai pas trop compris en fait.
Je veux juste donné un pointeur de fonction membre d'object quelcquonque au constructeur d'ActionListener.
Mais il veut rien savoir...

Reply

Marsh Posté le 09-11-2004 à 01:04:08    

c'est le addActionListener qui chie déjà, le reste je sais pas. c'est quoi le prototype de ton addActionListener ?
 
message d'erreur de compilation ?
 
toutes façons, ton code foire, tu manipules les pointeurs de fonctions n'importe comment. Apprends à les utilser, ou passe à une approche toute template.

Reply

Marsh Posté le 09-11-2004 à 01:17:59    

Code :
  1. template<typename T, typename RET, typename ARG>
  2. RET invoke(T &self, RET (T::*p)(ARG), ARG arg)
  3. {
  4.   return (self.*p)(arg);
  5. }
  6. class Foo
  7. {
  8. public:
  9.   float f(int);
  10.   bool g(bool);
  11.   bool h(Foo);
  12.   bool i(Foo *);
  13. };
  14. void test()
  15. {
  16.   Foo f;
  17.   invoke(f, &Foo::f, 3);
  18.   invoke(f, &Foo::g, true);
  19.   invoke(f, &Foo::h, Foo());
  20.   invoke(f, &Foo::i, static_cast<Foo*>(0));
  21. }

une version typée pas template, ça serait ça.

Reply

Marsh Posté le 09-11-2004 à 01:17:59   

Reply

Marsh Posté le 09-11-2004 à 01:19:12    

pour le protoype :
void addActionListener(ptr_ActionListener );
 
et le message d'erreur :
error C2440: 'initializing' : cannot convert from 'class ActionListener<void (__thiscall Test::*)(int,int,int)> *' to 'class ActionListener<ptrMethode> *'  
 
moi je me disais que c'était peu être à cause de  
 
//pointeur de fonction d'ActionListener
template<class ptrMethode>
typedef ActionListener<ptrMethode> *ptr_ActionListener;
 
par ce que dans le message d'erreur le compilateur à pas l'aire d'interpreter le template?


Message édité par peak le 09-11-2004 à 01:21:04
Reply

Marsh Posté le 09-11-2004 à 01:22:35    

ok parfait je vais tester ça!
Merci

Reply

Marsh Posté le 09-11-2004 à 09:04:52    

je sais pas, je comprends rien à ta boue, t'as toujours pas filé un seul morceau de code complet.

Reply

Marsh Posté le 09-11-2004 à 09:50:16    

on peut jouer à l'infini
 

Code :
  1. #include <functional>
  2. namespace
  3. {
  4.   struct ActionListenerBase : std::unary_function<void, int>
  5.   {
  6.     virtual void operator()(const int & ) =0;
  7.     virtual ~ActionListenerBase() { }
  8.   };
  9. }
  10. template<typename T>
  11. class ActionListener : ActionListenerBase
  12. {
  13.   T functor;
  14. public:
  15.   ActionListener(const T &t) : functor(t) { }
  16.   void operator()(const int &x) { return functor(x); }
  17. };
  18. #include <queue>
  19. #include <boost/shared_ptr.hpp>
  20. class Foo
  21. {
  22.   typedef boost::shared_ptr<ActionListenerBase*> Listener;
  23.   std::queue<Listener> listeners;
  24. public:
  25.   template<typename T>
  26.   void add_action_listener(const ActionListener<T> &al)
  27.   {
  28.     this->listeners.push_back(new ActionListener<T>(al));
  29.   }
  30. };

pour pouvoir foutre dedans tous ce qui permet d'écrire 'x(i)' retournant 'void'.
 
À voir aussi chez boost (pour ne pas réinventer la roue)
http://www.boost.org/doc/html/function.html && http://www.boost.org/libs/bind/bind.html (fantastiques)
 
Pour rester plus classique et faire sauter les limitations de STL
http://www.boost.org/libs/bind/mem_fn.html (généralisation/correction de STL)
http://www.boost.org/libs/functional/index.html (généralisation/correction de STL)

Reply

Marsh Posté le 09-11-2004 à 10:18:38    

En cadeau la définition des foncteurs généralisés d'A. Alexandrescu dans le livre "Modern C++ design".
 
L'auteur commence par définir un container de types calqué sur une liste façon Lisp, qu'il appelle Typelist. La version courte en est :

Code :
  1. // Fichier TypeList.h
  2. class NullType {};
  3. template <class T, class U>
  4. struct TypeList
  5. {
  6.     typedef T Head;
  7.     typedef U Tail;
  8. }
  9. #define TYPELIST_1(T1) TypeList<T1, NullType>
  10. #define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2)>
  11. #define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3)>
  12. // ... ad infinitum  
  13. // on peut allors faire, par exemple :
  14. typedef TYPELIST_3(short int, int, long int) EntiersSignes;


 
Dans la version longue, l'auteur définit tout un tas d'opérations sur les listes de types ainsi créées, comme le calcul de la longueur, un accès indexé, une opération de concaténation, de recherche, etc, opérations entièrement résolues à la compilation. Tout ça est pratique lorsqu'on veut définir des classes ou des fonctions avec un nombre variable de paramètres et des types indéterminés.
 
Ici on va se servir est l'accès indexé : on donne un index dans la liste et ça retourne le type correspondant:

Code :
  1. // index 0
  2. template <class Head, class Tail>
  3. struct TypeAt<TypeList<Head, Tail>, 0> {
  4.    typedef Head Result;
  5. };
  6. // index i non nul. Notez la récursivité ;)
  7. template <class Head, class Tail, unsigned char i>
  8. struct TypeAt<TypeList<Head, Tail>, i> {
  9.    typedef typename TypeAt<Tail, i-1>::Result Result;
  10. };


Ainsi TypeAt<EntiersSignes, 2> retourne le type long int.
 
Maintenant venons-en aux foncteurs proprement dits :

Code :
  1. // Fichier Functor.h
  2. #include <auto_ptr>
  3. #include "TypeList.h"
  4. //ParamList est un TypeList qui contient les parametres d'entrée
  5. // et Ret le retour de la fonction
  6. template <typename Ret>
  7. class FunctorImpl <Ret, NullType>
  8. {
  9.    virtual Ret operator()() = 0;
  10.    virtual FunctorImpl* clone() const = 0;
  11.    virtual ~FunctorImpl() {}
  12. };
  13. template <typename Ret, typename p1>
  14. class FunctorImpl <Ret, TYPELIST_1(p1)>
  15. {
  16.    virtual Ret operator()(p1) = 0;
  17.    virtual FunctorImpl* clone() const = 0;
  18.    virtual ~FunctorImpl() {}
  19. };
  20. template <typename Ret, typename p1, typename p2>
  21. class FunctorImpl <Ret, TYPELIST_2(p1, p2)>
  22. {
  23.    virtual Ret operator()(p1, p2) = 0;
  24.    virtual FunctorImpl* clone() const = 0;
  25.    virtual ~FunctorImpl() {}
  26. };
  27. // ...
  28. // classe concrete dérivée de FunctorImpl
  29. template <class ParentFunctor, typename fun>
  30. class FunctorHandler : FunctorImpl
  31.       <typename ParentFunctor::ResultType,
  32.        typename ParentFunctor::ParamList>
  33. {
  34. public:
  35.    typedef typename ParentFunctor::ResultType ResultType;
  36.    FunctorHandler(const Fun& fun) : fun_(fun) {}
  37.    FunctorHandler* clone() const {return new FunctorHandler(*this);}
  38.  
  39.    ResultType operator()() {return fun_();}
  40.    ResultType operator()(typename ParentFunctor::Param1 p1) {
  41.       return fun_(p1);
  42.    }
  43.    ResultType operator()(typename ParentFunctor::Param1 p1,
  44.                          typename ParentFunctor::Param1 p2) {
  45.       return fun_(p1, p2);
  46.    }
  47.    // ...
  48. private:
  49.    Fun fun_;
  50. }
  51. template <typename Ret, class ParamList = NullType>
  52. class Functor
  53. {
  54.   typedef FunctorImpl<Ret, ParamList> Impl;
  55.   typedef typename TypeAt<ParamList, 0>::Result Param1;
  56.   typedef typename TypeAt<ParamList, 1>::Result Param2;
  57.   typedef typename TypeAt<ParamList, 2>::Result Param3;
  58.   // ...
  59. public:
  60.    Functor() : pImpl_(0) {}
  61.    Functor(const Functor &rhs) : pImpl_(Impl::clone(rhs.pImpl_.get())) {}
  62.    Functor& operator=(const Functor &rhs) {
  63.          Functor copy(rhs);
  64.          // swap auto_ptrs by hand
  65.          Impl* p = pImpl_.release();
  66.          pImpl_.reset(copy.pImpl_.release());
  67.          copy.pImpl_.reset(p);
  68.          return *this;
  69.    }
  70.    Functor(std::auto_ptr<Impl> pImpl) : pImpl_(pImpl) {}
  71.    Ret operator()() {return (*pImpl_)();}
  72.    Ret operator()(Param1 p1) {return (*pImpl_)(p1);}
  73.    Ret operator()(Param1 p1, Param2 p2) {return (*pImpl_)(p1, p2);}
  74.    Ret operator()(Param1 p1, Param2 p2, Param3 p3) {return (*pImpl_)(p1, p2, p3);}
  75.    // etc
  76. private:
  77.    std::auto_ptr<Impl> pImpl_;
  78. }


 
Ca, c'est la version courte. [:itm]
 
A l'utilisation, ça donne:

Code :
  1. #include "TypeList.h"
  2. #include "Functor.h"
  3. #include <iostram>
  4. using namespace std;
  5. struct FoncteurTest {
  6.    void operator()(int i, double d) {
  7.       cout << "FoncteurTest::operator()(" << i << ", " << d << " ).\n";
  8.    }
  9. };
  10. int main()
  11. {
  12.    FoncteurTest f;
  13.    Functor<void, TYPELIST_2(int, double)> cmd(f);
  14.    cmd(4, 3.14);
  15. }


Message édité par el muchacho le 10-11-2004 à 17:10:47
Reply

Marsh Posté le 09-11-2004 à 10:22:10    

ouais ouais, boost::tuple pour la listequoi, boost toujours, boost vaincra !
 
explicit Functor(std::auto_ptr<Impl> spImpl);  
par contre ça c'est bidon, vu le transfert de propriété

Reply

Marsh Posté le 09-11-2004 à 10:27:41    

'fectivement, boost::tuple fait la même chose. D'ailleurs je ne serais pas étonné que boost::tuple soit inspiré de l'implémentation d'Alexandrescu dans Loki. C'est pourquoi la lib Loki d'Alexandrescu est un du coup un peu obsolète (c'est ce que j'ai mis dans mon CR de lecture dans le post ad'hoc), mais le bouquin permet de comprendre les choses.


Message édité par el muchacho le 09-11-2004 à 10:29:28
Reply

Marsh Posté le 09-11-2004 à 10:31:33    

bah Alexandrescu a rien inventé
et sans jamais l'avoir vu, tu très bien retrouvé ce genre de CRTP tout seul :)

Reply

Marsh Posté le 09-11-2004 à 10:46:15    

M'ouais, si j'ai du temps à perdre, quoi. [:spamafote]

Reply

Marsh Posté le 09-11-2004 à 11:11:15    

quoi ?

Reply

Marsh Posté le 09-11-2004 à 11:21:55    

Je suis en train de méditer sur vos post très instructifs (merci).  
Je commence à y voir plus claire même si tout est loin d'être limpide.
:ange:
 
Par exemple dans la version de Taz je ne comprend pas pourquoi ceci me donne ce message d'erreur?
 
error C2664: '__thiscall ActionListener<void (__thiscall Test::*)(int)>::ActionListener<void (__thiscall Test::*)(int)>(void (__thiscall Test::*const & )(int))' : cannot convert parameter 1 fro
m 'void (int)' to 'void (__thiscall Test::*const & )(int)'
 
C 'est comme si il considerait pas ma fonction "clickButtonActionPreformed" comme une fonction membre de Test :heink:
 

Code :
  1. class Test;
  2.   typedef void (Test::*TestFunctor) (int);
  3.   class Test{
  4.   public:
  5.   Foo f1;
  6.   Test(){
  7.    ActionListener<TestFunctor> al(clickButtonActionPreformed);
  8.   }
  9.   void clickButtonActionPreformed(int );
  10.   };
  11.   void Test::clickButtonActionPreformed(int val){
  12.  cout<<"clickbutton"<<endl;
  13.   }
  14.   void main(){
  15.   Test t1;
  16.   }

Reply

Marsh Posté le 09-11-2004 à 11:30:49    

t'as rien compris ... &Test:: à la limite, mais ce n'est pas là l'usage qu'il faut en faire. Toute façon tu n'iras pas plus loin
 
T'es complètement perdu ... commence par voir comment on se sert d'un pointeur de fonction membre. Là t'en chie, alors je te file des pistes pour des cas génériques. Des liens pour tout planquer, ça passe comme une lettre à la poste, mais t'as pas l'air d'être intéressé par les liens ...


Message édité par Taz le 09-11-2004 à 11:31:44
Reply

Marsh Posté le 09-11-2004 à 11:39:00    

sisi, c juste que je pensais que le ... &Test:: était implicite et que ça pourrait marcher comme ça...
 
edit: ceci dis c'est vrai que je suis un peu paumé


Message édité par peak le 09-11-2004 à 11:40:50
Reply

Marsh Posté le 09-11-2004 à 11:51:57    

ISO C++ interdit de prendre l'adress d'un membre de fonction non statique non qualifié ou entre parenthèses pour former un pointeur d'un membre de fonction. Utilisers «&Test::clickButtonActionPreformed»

Reply

Marsh Posté le 09-11-2004 à 14:50:58    

Pour le deuxième exemple de Taz, mon compilo apprecie pas le push_back dans un vector :
 
'push_back' : cannot convert parameter 1 from 'class ActionListener<void (__thiscall Test::*)(int)> *' to 'const class boost::shared_ptr<struct `anonymous namespace'::ActionListene
rBase *> &'
 
J'avais cru comprendre que "boost:shared_ptr"
servais justement à eviter ça; mais apparement j'ai du encore me planter  :pfff:  
 
(en passant je me demandais aussi pourquoi on utilisait un namespace anonyme pour ActionListenerBase?)

Reply

Marsh Posté le 09-11-2004 à 15:03:39    

compilateur de merde

Reply

Marsh Posté le 09-11-2004 à 15:20:35    

lol,
je compile avec visual par ce que j'ai commencé mon projet avec mais la prochaine étape (apres l'API) c'tai de porter le code sous g++...en attendant vous avez une idée d'une solution temporaire?
 
Au pire je pense pouvoir utiliser des poiteurs void à la place de références d'ActionListener... je vais tester ça ...

Reply

Marsh Posté le 09-11-2004 à 16:11:54    

Si t'es sous VC7.1, en principe ça devrait passer, si t'es sous VC6, tu peux oublier Boost.

Reply

Marsh Posté le 09-11-2004 à 16:29:20    

j'ai pas de bol aujourd'hui! J'ai VC6.
Mais merci c'est bon à savoir; si je ne trouve pas de solution   je m'arrangerai pour me le procurer.  

Reply

Marsh Posté le 09-11-2004 à 18:59:13    

Et ma solution ? A défaut de Boost, tu peux quand même utiliser Loki, qui est quand même puissant, et qui a été porté sur VC6.


Message édité par el muchacho le 09-11-2004 à 19:19:59
Reply

Marsh Posté le 09-11-2004 à 19:17:00    

autant utiliser boost::function, c'est beaucoup meilleur à toutes nos sortes de hack.
 
Mais le problème, c'est la conception : si tu veux avoir une collection hétérogène d'objets callbacks, il faut que tu définies une interface, etc

Reply

Marsh Posté le 09-11-2004 à 19:21:48    

Taz a écrit :

autant utiliser boost::function, c'est beaucoup meilleur à toutes nos sortes de hack.
 
Mais le problème, c'est la conception : si tu veux avoir une collection hétérogène d'objets callbacks, il faut que tu définies une interface, etc


 
Houlala, ton français s'améliore de jour en jour. Et il est sous VC6, on a dit.


Message édité par el muchacho le 09-11-2004 à 19:23:27
Reply

Marsh Posté le 09-11-2004 à 19:55:33    

c'est un peu fait exprès :)
 
et je sais pas, y a beaucoup de bricolage dans boost pour que ça marche avec VC6, faudrait voir à quand même essayer.
 
Moi je pense que t'es pas prêt pour les template. Commence à comprendre comment ça fonctionne les pointeurs de fonctions membres, fait du polymorphisme et voilà


Message édité par Taz le 09-11-2004 à 19:57:33
Reply

Marsh Posté le 10-11-2004 à 00:46:51    

Je vais suivre vos conseils... en tous cas j'ai appris pas mal de trucs...merci bien!
 
Ps : j'ai un solution qui m'a quand même l'aire pas trop mal; je ne donne finalement à mon controller que des pointeurs de fonctions membres d'actionListener (pas d'actionListener) et ai apparement plus besoin de template...je fait en suite une liste de pointeurs de fonctions membres d'ActionListener dans mon controller (et bon là j'ai encore un tit prob mais bon ça devrait être arrangeable)
 
A+

Reply

Marsh Posté le 10-11-2004 à 00:50:27    

t'as bien compris la syntaxe d'appel etc ?

Reply

Marsh Posté le 10-11-2004 à 01:00:34    

Je pense que ça ça devrait aller (avec quelques tests)... par contre je viens de passer une heure à pas comprendre pourquoi si j'ai un tableau static de pointeurs de fonctions membres d'ActionListener et que je l'initialise avec :
 
ActionListenerFunctor** Controller::actions(NULL);
 
il veut rien savoir alors que si je lui donne pas de valeur :
 
ActionListenerFunctor** Controller::actions;
 
il passe et le considère comme assigné à NULL mais bon je sors un peu du sujet du topic là .... :sweat:  
 

Reply

Marsh Posté le 10-11-2004 à 02:32:24    

static ?
 
utilise l'initialisation par copie (= 0);
 
mais pourquoi ne pas utiliser un vector ?

Reply

Marsh Posté le 10-11-2004 à 05:27:41    

Passe à VC7 en plus c'est gratuit:
http://msdn.microsoft.com/visualc/vctoolkit2003/

Reply

Marsh Posté le 10-11-2004 à 09:59:43    

Quelques corrections dans le code que j'ai donné (attention, non testé, mais l'essentiel y est).

Reply

Marsh Posté le 10-11-2004 à 12:01:56    

Ma première idée c'était de faire un  
 
static std::vector<ActionListenerFunctor*> actions[NBR_ACTION_TYPES];
 
En fait chaque composants de l'API a une table dans laquelle il garde ses pointeurs et il passe au controller l'adress de l'entré de sa table pour pouvoir  
 
gérer ses pointeur localement et changer de fonction puis effacer l'enter à la destruction du composant.
 
Mais j'ai un  
error C2036: 'class std::vector<void (__thiscall ActionListener<_Ty>::**)(int,int,int),class std::allocator<void (__thiscall  
 
ActionListener<_Ty>::**)(int,int,int)> > *' : unknown size
//d'ailleur malgré la doc je comprend pas trop cette erreur dans mon cas
et plus chiant ;  
error C2662: 'push_back' : cannot convert 'this' pointer from 'class std::vector<void (__thiscall ActionListener<_Ty>::**)(int,int,int),class  
std::allocator<void (__thiscall ActionListener<_Ty>::**)(int,int,int)> >' to 'class std::vector<_Ty,_A> &'
 
donc je m'était dis qu'un matrice ferait l'affaire ...
Mais évidement ça pouvais pas simplement marcher donc j'ai un problème d'allocation complètement débile; le compilateur ne détecte pas d'erreur mais dans le constructeur de Controller quand je fait :

Code :
  1. //...
  2. ActionListenerFunctor** Controller::actions;
  3. //j'ai simplifier l'histoire de la table locale le temps que ça marche  
  4. //sinon j'aurai ActionListenerFunctor*** Controller::actions;
  5. Controller() {
  6.  if(actions==NULL){
  7.   actions=new ActionListenerFunctor* [NBR_ACTION_TYPES];
  8.   for(unsigned i=0; i<NBR_ACTION_TYPES; i++){
  9.    actions[i]=new ActionListenerFunctor [INIT_CONTOLLER_LENGHT];
  10.    for(unsigned j=0; j<INIT_CONTOLLER_LENGHT; j++){
  11.     cout<<&actions[i][j]<<endl;
  12.     actions[i][j]=NULL;
  13.    }
  14.   }
  15.  }
  16. }


 
 si #define INIT_CONTOLLER_LENGHT 6 no prob
 si #define INIT_CONTOLLER_LENGHT 7 no prob
 si #define INIT_CONTOLLER_LENGHT 8 segmentation fault!?
 
0x049B1D30
0x049B1D38
0x049B1D40
0x049B1D48
0x049B1D50
0x049B1D58
0x049B1D60
0x00000038    plantage!
 
A croire que j'ai offensé le tout puissant par ce que là je vois pas le rapport !?
 
Sinon je met dans les pages de man qu'on peux pas avoir plus que 6compossants  :D et que faudra attendre la version 2.0 mais je commence à fortement douter que mon projet révolutionne le monde de l’informatique ce qui était pourtant ça vocation première...
 
LeGreg :
Passe à VC7 en plus c'est gratuit:
http://msdn.microsoft.com/visualc/vctoolkit2003/  
 
Ha tiens je savais pas que c'était gratuit je vais tester ça!, mais d'abord finir 2-3 autres details (style aujourd'hui je dois absolument commenter (j'ai 3000lignes du proj sans un comment) ... sans doute le truc le plus chiant de la semaine d'ailleurs...)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed