2009-10-08 5 views
0

Voici un résumé de mon code. Je suis en train d'utiliser glutSpecialFunc pour dire utiliser GLUT ma fonction KeyPressErreur C2664 dans une tentative de faire un peu OpenGl en C++

class Car : public WorldObject 
{ 
public: 
void KeyPress(int key, int x, int y) 
{ 
} 

Car() 
{ 
    glutSpecialFunc(&Car::KeyPress); // C2664 error 
} 
} 

Le message d'erreur que je reçois est:

Error 1 error C2664: 'glutSpecialFunc' : cannot convert parameter 1 from 'void (__thiscall Car::*)(int,int,int)' to 'void (__cdecl *)(int,int,int)' c:\users\thorgeir\desktop\programmingproject1\quickness\quickness\car.cpp 18 Quickness 
+0

Cette question devrait être repellée comme Visual Studio, ou Visual-C++ –

Répondre

2

Votre fonction est membre d'une classe. Lorsque vous faites quelque chose comme Car c; c.drive(), cette fonction drive() a besoin d'une voiture pour travailler. C'est le pointeur this. Donc, la surabondance ne peut pas appeler cette fonction si elle n'a pas de voiture pour travailler, elle attend une fonction gratuite.

Vous pourriez rendre votre fonction static, ce qui signifierait que la fonction ne fonctionne pas sur une voiture. la surabondance sera alors capable de l'appeler, mais je suppose que vous voulez manipuler une voiture. La solution est de faire fonctionner le passer de l'appel sur un objet, comme celui-ci:

void key_press(int key, int x, int y) 
{ 
    activeCar->KeyPress(key, x, y); 
} 

activeCar est un certain pointeur globalement accessible à la voiture. Vous pouvez le faire avec une sorte de singleton CarManager. CarManager conserve la trace de la voiture active en cours de contrôle. Ainsi, lorsque vous appuyez sur une touche, vous pouvez la transmettre. CarManager::reference().active_car().KeyPress(key, x, y). Un singleton est un objet qui n'a qu'une seule instance accessible globalement. Il est en dehors de la portée de la réponse, mais vous pouvez Google pour diverses ressources sur la création d'un. Recherchez Meyers Singleton pour une solution simple singleton.

Une approche différente consiste à avoir une sorte de singlet InputManager, et ce gestionnaire gardera une trace de la liste des objets qu'il doit notifier des pressions sur les touches. Cela peut se faire de plusieurs façons, le plus simple serait quelque chose comme ceci:

class InputListener; 

class InputManager 
{ 
public: 
    // ... 

    void register_listener(InputListener *listener) 
    { 
     _listeners.push_back(listener); 
    } 

    void unregister_listener(InputListener *listener) 
    { 
     _listeners.erase(std::find(_listeners.begin(), _listeners.end(), listener)); 
    } 

    // ... 

private: 
    // types 
    typedef std::vector<InputListener*> container;   

    // global KeyPress function, you can register this in the constructor 
    // of InputManager, by calling glutSpecialFunc 
    static void KeyPress(int key, int x, int y) 
    { 
     // singleton method to get a reference to the instance 
     reference().handle_key_press(key, x, y); 
    } 

    void handle_key_press(int key, int x, int y) const 
    { 
     for (container::const_iterator iter = _listeners.begin(); 
      iter != _listenders.end(), ++iter) 
     { 
      iter->KeyPress(key, x, y); 
     } 
    } 

    container _listeners; 
}; 

class InputListener 
{ 
public: 
    // creation 
    InputListener(void) 
    { 
     // automatically add to manager 
     InputManager::reference().register_listener(this); 
    } 

    virtual ~InputListener(void) 
    { 
     // unregister 
     InputManager::reference().unregister_listener(this); 
    } 

    // this will be implemented to handle input 
    virtual void KeyPress(int key, int x, int y) = 0; 
}; 

class Car : public InputListener 
{ 
    // implement input handler 
    void KeyPress(int key, int x, int y) 
    { 
     // ... 
    } 
}; 

Bien sûr, ne hésitez pas à poser plus de questions si cela n'a pas de sens.

+1

Wow bonne réponse et très rapide !. Tout expliqué. – Thorgeir

0

Ce que je fini par faire était

Ajout:

virtual void KeyPress(int key, int x, int y) {}; 

à la classe WorldObject

Et bulle de l'événement à la voiture.

void KeyPressed(int key, int x, int y) 
    { 
     KeyPress(key,x,y); 

     list<WorldObject*>::iterator iterator = ChildObjects.begin(); 
     while(iterator != ChildObjects.end()) 
     { 
      (*iterator)->KeyPressed(key,x,y); 
      iterator++; 
     } 
    } 
Questions connexes