www.MignonSoft.com - Développement C++
C++ (3 éléments)
voir aussi:: Questions sans reponces
:: Présentation ::

Questions / Réponses sur du code source C/C++ assez avancé:

[R1] Utisation de methode/class static
[R2] Appel de methode/class par un pointeur
[R3] Gestion d'evenement par pointeur sur class
[R4] Comment placer un timer en "pause" (fonction PauseTimer/ReleaseTimer)

 

:: C++::

[R1] Utisation de methode/class static

class Test 

public : 
  
static int nbInstance; 
  Test() { nbInstance++; } 
  
static int fonc() { return nbInstance;   } 
}; 

int Test::nbInstance = 0; // sinon la variable na pas d'instansiation

void main() { 
  
// nbInstance =0; 
  Test test; // nbInstance =1; 
  Test::fonc(); // valide 
  test.nbInstance; // valide 
  test.fonc(); // valide 

[R2] Appel de methode/class par un pointeur

class Test {
public:
  
void Methode1(int param1) { printf("Methode1(%d)\n",param1); }
  
void Methode2(int param1) { printf("Methode2(%d)\n",param1); }  
};
void Function1(int param1) { printf("Function1(%d)\n",param1); }
void Function2(int param1) { printf("Function2(%d)\n",param1); }

void main () {
  
// appel par pointeur sur fonction
  typedef void (*Function)(int);
  Function function;
  function=Function1;
  function(10);
  function=Function2;
  function(20);

  
// appel par pointeur sur methode
  typedef void (Test::*Methode)(int);
  Methode methode;
  Test test; 
// il faut fatalement un "this" pour appeler une methode
  methode=Test::Methode1;
  
//test.methode(30); // dommage mais c'est impossible, "methode" ne fait pas partie de la class !!
  (test.*methode)(30); // syntax tres laide
  methode=Test::Methode2;
  (test.*methode)(40);
}

Resultat:
Function1(10)
Function2(20)
Methode1(30)
Methode2(40)

[R3] Gestion d'evenement par pointeur sur class

Cette article repond aussi a la question: comment faire un pointeur sur methode quelquonque.

class Class {
public:
  
typedef void (Class::*Methode)(); // type un pointeur sur methode
  void *ptrThis;    // pointeur sur le this de la class
  Methode methode;  // pointeur sur une methode generique

  Class() { Set(NULL,NULL); }
  
void Set(void *_ptrThis,Methode _methode) {
    ptrThis = _ptrThis;  
// affectation des nouvelles valeurs
    methode = _methode;
  }
  
#define SetIt(_ptrThis,_methode) Set(_ptrThis,(Class::Methode)_methode) // pour simplifier l'ecriture
};

#define Call0Param(ptrClass) \
typedef void (Class::*Methode)(); \
Methode methode = (Methode) (ptrClass)->methode; \
((Class *)((ptrClass)->ptrThis)->*methode)(); \
}
#define Call1Param(ptrClass,t1,p1) \
typedef void (Class::*Methode)(t1);\
 Methode methode = (Methode) (ptrClass)->methode;\
 ((Class *)((ptrClass)->ptrThis)->*methode)(p1); \
}
#define Call2Param(ptrClass,t1,p1,t2,p2) \
{ \
typedef void (Class::*Methode)(t1,t2); \  
Methode methode = (Methode) (ptrClass)->methode; \
((Class *)((ptrClass)->ptrThis)->*methode)(p1,p2); \
 }

// Les differant call suivant le nombre de parametres (avec valeur de retour)
#define Call0ParamR(ptrClass,tr,pr) { typedef tr (Class::*Methode)(); Methode methode = (Methode) (ptrClass)->methode; pr = ((Class *)((ptrClass)->ptrThis)->*methode)(); }
#define Call1ParamR(ptrClass,tr,pr,t1,p1) { typedef tr (Class::*Methode)(t1); Methode methode = (Methode) (ptrClass)->methode; pr = ((Class *)((ptrClass)->ptrThis)->*methode)(p1); }
#define Call2ParamR(ptrClass,tr,pr,t1,p1,t2,p2) { typedef tr (Class::*Methode)(t1,t2); Methode methode = (Methode) (ptrClass)->methode; pr = ((Class *)((ptrClass)->ptrThis)->*methode)(p1,p2); }

class A {
public:
  
int valueA; // simplement pour montrer un element du this valide
  A(int value) { valueA = value; }
  
int MethodeA1() {
    printf("[valueA=%d] MethodeA1()\n",valueA);
    
return valueA;
  }
  
void MethodeA2(int p1) { 
    printf("[valueA=%d] MethodeA2(%d)\n",valueA,p1);
  }
};

class B {
public:
  
int valueB; // simplement pour montrer un element du this valide
  B(int value) { valueB = value; }
  
void MethodeB1(int p1) { 
    printf("[valueB=%d] MethodeB1(%d)\n",valueB,p1);
  }
  
void MethodeB2(int p1,float p2) {
    printf("[valueB=%d] MethodeB2(%d,%f)\n",valueB,p1,p2);
  }
};

void main()
{
  A a(1);
  B b(2);

  Class class1,class2,class3;
  class1.SetIt(&a,A::MethodeA1);
  class2.SetIt(&b,B::MethodeB1);
  class3.SetIt(&b,B::MethodeB2);

  
int result;
  Call0ParamR(&class1,
int,result);    // <=> result = a.MethodeA1();
  printf("Result:%d\n",result);
  Call1Param(&class2,
int,3);        // <=> b.MethodeB1(3);      
  Call2Param(&class3,int,4,float,5.5f);  // <=> b.MethodeB2(4,5.5f);

  // clairement ce system d'appel de methode par CallxParamX() a un gros default:
  // il ne verifie pas l'integrité des passages de parametres
  // on peut tres bien faire un appel a un methode qui attend 2 argument alors
  // que l'on en passe q'un seul, pas de pb a la compil, mais erreur a l'execution
  // ex.: Call1Param(&class3,int,4);  // <=> b.MethodeB2(4,???); alors deMethodeB2 a 2 param
}

Resultat:
[valueA=1] MethodeA1()
Result:1
[valueB=2] MethodeB1(3)
[valueB=2] MethodeB2(4,5.500000)

[R4] Comment placer un timer en "pause" (fonction PauseTimer/ReleaseTimer)
Seul existent les API SetTimer et KillTimer.
Recherche fonction du type int GetTimer(HWND hWnd,int id) qui donnerai le elapsed time d'un timer déjà Initialisé par SetTimer().
Mon but est de pouvoir faire un pause/resume de timer quand un MessageBox est utilisér
(pour débuguer de l'OpenGL ça peut être très utile Mais les seuls API windows sur le sujet sont SetTimer / KillTimer() qui ne donnent pas les infos sur l'ement killer, sinon ça serait trop simple)

Reponces:
Pause: SetTimer ( hWnd , id , 0x7fffffff , NULL ) ;
Release:  SetTimer ( hWnd , id , periodeOriginal , NULL );

 

:: Questions sans réponses::

[Q1] La déclaration de fonction suivante est compilable, mais jamais utilisable, a quoi cela peut il servir ?
void MaFonction(...) ;

 

Acceuil | Haut de page | Rapporter une erreur