C2664 Fehler in einem Versuch, einige OpenGl in c ++ zu tun
Frage
Hier ist ein Auszug aus meinem Code. Ich versuche glutSpecialFunc zu verwenden Schwemme zu sagen, meine KeyPress-Funktion verwenden
class Car : public WorldObject
{
public:
void KeyPress(int key, int x, int y)
{
}
Car()
{
glutSpecialFunc(&Car::KeyPress); // C2664 error
}
}
Die Fehlermeldung ich erhalte, ist:
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
Lösung
Ihre Funktion ist ein Mitglied einer Klasse. Wenn Sie so etwas wie Car c; c.drive()
tun muss, dass drive()
Funktion mit einem Auto zur Arbeit. Das ist der this
Zeiger. So Schwemmt diese Funktion nicht aufrufen kann, wenn es nicht ein Auto zur Arbeit an hat, ist es eine kostenlose Funktion erwartet.
Sie können Ihre Funktion static
machen, die die Funktion würde bedeuten, nicht auf ein Auto betreiben. Schwemme wird dann in der Lage sein, es zu nennen, aber ich nehme an, Sie wollen ein Auto manipulieren. Die Lösung ist, die Funktion Anruf übergeben Sie die auf ein Objekt, wie folgt aus:
void key_press(int key, int x, int y)
{
activeCar->KeyPress(key, x, y);
}
Wo activeCar
einige global zugänglichen Zeiger auf dem Auto. Sie können mit irgendeiner Art von CarManager
Singletons dies tun.
CarManager verfolgt die Spuren des aktiven Autos gesteuert werden, so dass, wenn eine Taste gedrückt wird man es weitergeben kann. CarManager::reference().active_car().KeyPress(key, x, y)
Ein Singleton ist ein Objekt, das nur eine global zugängliche Instanz hat. Es liegt außerhalb des Umfangs der Antwort, aber Sie können Google für verschiedene Ressourcen auf einem zu schaffen. Look up Meyers Singleton für eine einfache Singleton Lösung.
Ein anderer Ansatz ist es, eine Art von Inputmanager Singleton zu haben, und dieser Manager Spur einer Liste von Objekten hält sie von Tastendrücken mitteilen sollten. Dies kann in einigen Arten erfolgen, die am einfachsten so etwas wie dies wäre:
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)
{
// ...
}
};
Natürlich fühlen sich frei, mehr Fragen zu stellen, wenn dies keinen Sinn macht.
Andere Tipps
Was ich am Ende tat
Hinzufügen:
virtual void KeyPress(int key, int x, int y) {};
auf die WorldObject Klasse
Und Blase das Ereignis an das Auto.
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++;
}
}