C++ OpenGL => Comment fait-on un pointeur sur méthode ?

Résolu
Phenix_ent Messages postés 5 Date d'inscription mercredi 28 décembre 2005 Statut Membre Dernière intervention 29 décembre 2005 - 28 déc. 2005 à 19:11
KeniiyK Messages postés 326 Date d'inscription vendredi 13 août 2004 Statut Membre Dernière intervention 2 novembre 2007 - 27 janv. 2006 à 10:55
Bonjour,

Voilà, je développe un module graphique pour un jeu. L'OpenGL a besoin d'un pointeur sur fonction pour le display, mais ma fonction est dans une class et j'arrive pas a faire fonctionner ca :(

void CGomokuDisplay::InitBoard(int ac, char **av, int PosX, int PosY, int Height, int Width)
{
glutInit(&ac, av);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(Height, Width);
glutInitWindowPosition(PosX, PosY);
glutCreateWindow(av[0]);

glutDisplayFunc(_Display);
}

void CGomokuDisplay::_Display()
{
/*Le code pour le display*/
}

La class :
class CGomokuDisplay
{
private:
void _Display(); // Fonction d'affichage principale
public:
CGomokuDisplay();
~CGomokuDisplay();

void InitBoard(int ac, char **av, int PosX, int PosY, int Height, int Width); // Initialise la fenetre openGL
};

Dans une class, une méthode public peut acceder à une méthode privée, mais pour faire un pointeur dessus ....

Merci de vos réponses

11 réponses

luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
28 déc. 2005 à 21:16
Normal que ca ne marche pas, c'est impossible de pointer sur la fonction membre qui n'est pas static.
3
nightlord666 Messages postés 746 Date d'inscription vendredi 17 juin 2005 Statut Membre Dernière intervention 23 mai 2007 10
29 déc. 2005 à 10:51
Une methode normale de ta classe ne peut pas être appellée sans instance. Tu dois faire :

MaClasse myclass = new MaClasse();
myclass->methodeNormale();

Avec une methode statique, tu peut faire comme ça :

MaClasse::methodeStatique();

Et tu n'a pas besoin d'allouer de mémoire.

Autre exemple(car tu parle des types de retour) :

class MaClasse
{
public:
static int add(int a, int b);
static void afficher(char* chaine);
int sous(int a, int b);
};

int MaClasse::add(int a, int b)
{
return a + b;
}

void MaClasse::afficher(char* chaine)
{
printf(chaine);
}

int MaClasse::sous(int a, int b)
{
return a - b;
}

int main(int argc, char **argv)
{
//Methodes statiques : pas d'allocation
int n = MaClasse::add(1, 2);
MaClasse::afficher(n); //Affichera 3

//Methodes normales dans la classe : allocation
MaClasse my = new MaClasse();
int n2 = my->sous(2, 1);

//Encore une methode statique
MaClasse::afficher(n2); //Affichera 1

return 0;
}

Pour en revenir à la question, OpenGL acceptera uniquement des méthodes statiques car il ne peut pas créer d'instance de ta classe et lui allouer de la mémoire. Il faut donc lui donner comme methode une methode statique.

J'espère que tu as compris, car c'est quand même les bases de la POO en C++ !
3
Phenix_ent Messages postés 5 Date d'inscription mercredi 28 décembre 2005 Statut Membre Dernière intervention 29 décembre 2005
28 déc. 2005 à 21:56
Ok, merci bien, maintenant ca fonctionne.
J'ai rendu la méthode display static et ca fonctionne.

class CGomokuDisplay
{
private:
static void _Display(); // Fonction d'affichage principale
public:
CGomokuDisplay();
~CGomokuDisplay();

void InitBoard(int ac, char **av, int PosX, int PosY, int Height, int Width); // Initialise la fenetre openGL
};

Une dernière question, je vois pas trop ce que ca change de rendre la méthode static (à part que ca fonctionne), vu qu'elle retour void ...
Peux-tu m'aider la dessus ?
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
29 déc. 2005 à 00:16
Bonne question, doit y avoir un problème d'adresse avec une fonction membre normal. Mais je peux pas t'en dire plus.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Phenix_ent Messages postés 5 Date d'inscription mercredi 28 décembre 2005 Statut Membre Dernière intervention 29 décembre 2005
29 déc. 2005 à 00:22
Ok merci ;)
0
nightlord666 Messages postés 746 Date d'inscription vendredi 17 juin 2005 Statut Membre Dernière intervention 23 mai 2007 10
29 déc. 2005 à 10:12
Il faut la rendre statique, comme ça, OpenGL ne doit pas créer d'Instance de la classe pour y accèder(comme toi tu peut y accèder sans créer d'instance). Mais dans une méthode statique, tu ne peut pas utiliser les autres membres de la classe si ils ne sont pas statiques.
0
Phenix_ent Messages postés 5 Date d'inscription mercredi 28 décembre 2005 Statut Membre Dernière intervention 29 décembre 2005
29 déc. 2005 à 10:20
Donc si je veux appeler une autre méthode de ma class dans "display", je devrais également la rendre static ?
Mais ce que je comprends pas bien, c'est ce que ca change de rendre une méthode static ou non, surtout quand elle renvoie void (mais bon, je pige pas non plus si c'était un int)
0
Phenix_ent Messages postés 5 Date d'inscription mercredi 28 décembre 2005 Statut Membre Dernière intervention 29 décembre 2005
29 déc. 2005 à 12:00
Ok, oui c'est bon, j'ai compris (enfin je pense).
Donc, une methode static peut etre considérée comme une fonction hors d'un objet (en terme d'appel), sauf si elle est privée.
Ce qui me manquait pour comprendre, c'est que j'avais pas pensé à allocation de la mémoire pour l'objet (ce qui effectivement pour opengl ne peut pas marcher).

Merci beaucoup pour les explications.
0
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
29 déc. 2005 à 12:21
C'est pas un problème d'adresse pour les fonctions membres normales, mais un problème de convention d'appel
0
KeniiyK Messages postés 326 Date d'inscription vendredi 13 août 2004 Statut Membre Dernière intervention 2 novembre 2007 2
27 janv. 2006 à 10:52
Salut, je vous propose juste un petit complément pour les pointeurs de fonctions :

class PtrFunc
{
public :
static PtrFunc _instance1;
static PtrFunc _instance2;


static void Initialize(void)
{
_instance1._ptrFunc=_instance2.FuncPtr;
_instance2._ptrFunc=_instance1.FuncPtr;
}


void CallPtr()
{
(this->*_ptrFunc)();
}


private :
PtrFunc(int i)
{
_int=i;
_ptrFunc=NULL;
}

PtrFunc() {}

int _int;


void (PtrFunc::*_ptrFunc)(void);


void FuncPtr()
{
std::cout << "appel de la fonction pointee " << _int << std::endl;
}
};

PtrFunc PtrFunc::_instance1(1);
PtrFunc PtrFunc::_instance2(2);

int main()
{
PtrFunc::Initialize();
PtrFunc::_instance1.CallPtr();
PtrFunc::_instance2.CallPtr();
return 0;
}

Passez au debugger dans la methode initialize les pointeurs de fonction des 2 instances pointent au même endroit !!!!!
Executer... "l'appel n'est pas inversé".... i.e.: on a bien _int==1 puis _int==2....
Ce qui veut dire que c'est la même fonction qui est appelée mais dans un contexte différent -> l'instance en fait...

@+ KeniiyK
0
KeniiyK Messages postés 326 Date d'inscription vendredi 13 août 2004 Statut Membre Dernière intervention 2 novembre 2007 2
27 janv. 2006 à 10:55
Pour bien se rendre compte que c'est la même function qui est appelée, changez la fonction FuncPtr comme suit :

void FuncPtr()
{
static nombreAppel=0;
std::cout << "appel de la fonction pointee " << _int << " nombre d'appel " << nombreAppel++<< std::endl;
}

KeniiyK
0
Rejoignez-nous