2010-01-02 2 views
2

point à objet que je suis nouveau sur C++ et je suis en train de faire des tests avec C++ et SDL et SDL, nous avons une fonction:C++/SDL « void * » est pas un type

SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param); 

que je peux passer un rappel pour le temporisateur créé. Mais apparemment, il convertit mon instance à * void, donc je ne peux pas le récupérer sur la méthode de mise à jour qui est statique, et c'est intéressant, mais le SDL_AddTime ne fonctionne pas sur une fonction de rappel non statique.

Eh bien, mon problème est que lorsque vous essayez d'appeler la méthode publique rendu par le vide * argument param Il se plaint de ne pas être un pointeur à type d'objet ...

Est-il possible que je peut obtenir l'instance de caractère à nouveau dans la méthode de mise à jour puisque je n'ai pas le contrôle sur la fonction SDL_AddTime et que je dois passer les paramètres requis?

Merci

#include "Character.h" 

Character::Character(void) 
{ 
    timer = SDL_AddTimer(33, update, this); 
    this->render(); // is called without problem 
} 

//static method 
Uint32 Character::update(Uint32 interval,void* param) 
{ 
    param->render(); // yields: 'void*' is not a pointer-to-object type; 

    SDL_Event event; 

    event.type = SDL_USEREVENT; 
    event.user.code = 1020; 
    event.user.data1 = param; 

    SDL_PushEvent(&event); 

    return interval; 
} 

void Character::render(void) 
{ 
    printf("rendering character \n"); 
} 
+0

La raison de ceci est facilement apparente. Les types définissent les opérations que vous pouvez effectuer sur les données. 'void *' indique un pointeur vers un type inconnu. Quelles opérations pouvons-nous effectuer sur un type inconnu? – GManNickG

+0

Salut GMan, donc vous dites que le principe de ce * paramètre vide est de ne pas être utilisé, pourriez-vous s'il vous plaît m'aider à dire si cette approche serait correcte ou peut-être utiliser une autre façon? Merci beaucoup :) – zanona

+0

FWIW, vous ne pouvez pas utiliser un pointeur vers la méthode non statique car ceux-ci ont un type différent en C++, et votre API (la fonction SDL_AddTimer) n'attend pas ce type. –

Répondre

5

Vous n'avez pas besoin d'un reinterpret_cast - un static_cast devrait être OK:

Character * cp = static_cast <Character *>(param); 

Vous devez éviter reinterpret_cast - il est presque toujours spécifique à l'implémentation, et peut masquer des problèmes - tout comme les distributions C de style ancien.

+0

Mais static_cast n'est-il pas fait sans vérification de type ou quoi que ce soit, ce qui en fait exactement le style C? – LiraNuna

+0

Non, ce n'est pas le cas - les règles sont un peu compliquées, mais elles font ce que STATIC (c'est-à-dire à la compilation) peut faire. Sinon, il serait identique à reinterpret_cast. –

+1

Ironiquement, Lira, c'est ce que 'reinterpret_cast' fait. 'reinterpret_cast' dit" traiter X comme Y "et le compilateur va" Ok! ". 'static_cast' dit" Traitez X comme Y, mais assurez-vous que cette conversion est définie et utilisez cette méthode. " et le compilateur soit "Ok, je vois comment" ou "Nope". Pour les pointeurs, vous pouvez implicitement transtyper 'T *' en' void * ', et' static_cast' dans l'autre sens. – GManNickG

2

Cast your pointeur param à un personnage:

Character * charPtr = reinterpret_cast<Character *>(param); 
charPtr->render(); 
2

La raison en est que C++ est un langage fort typé. Pour changer un type à l'autre, vous devez jeter d'abord:

Uint32 Character::update(Uint32 interval, void* param) 
{ 
    reinterpret_cast<Character* >(param)->render(); 

    /* ... */ 
} 
2

Juste pour référence, si vous deviez appeler beaucoup de choses dans une fonction, pour sauver tous les trucs de reinterpret_cast méchant partout où vous pouvez faire

Character * myCharacter = reinterpret_cast<Character* >(param);

Ce qui permet de vous faire « myCharacter-> rendre();' ou whathaveyou ...

Questions connexes