Domanda

Ecco un estratto del mio codice. Sto cercando di utilizzare glutSpecialFunc per dire sovrabbondanza di usare la mia funzione KeyPress

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

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

Il messaggio di errore che ottengo è:

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
È stato utile?

Soluzione

La vostra funzione è un membro di una classe. Quando fai una cosa del genere Car c; c.drive(), quella funzione drive() bisogno di una macchina con cui lavorare. Questo è il puntatore this. Quindi eccesso non può chiamare tale funzione, se non ha una macchina su cui lavorare, è in attesa di una funzione libera.

Si potrebbe fare la vostra funzione static, il che significherebbe la funzione non funziona su una macchina. eccesso sarà quindi in grado di chiamarlo, ma suppongo che si desidera modificare una macchina. La soluzione è quella di rendere la funzione passarlo di chiamata su un oggetto, in questo modo:

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

Dove activeCar qualche puntatore globalmente accessibile per auto. È possibile farlo con una sorta di CarManager Singleton.

CARMANAGER tiene traccia della macchina attiva controllato, in modo che quando si preme un tasto si può passare sopra:. CarManager::reference().active_car().KeyPress(key, x, y)

Un singleton è un oggetto che ha un solo esempio globalmente accessibile. E 'al di fuori del campo di applicazione della risposta, ma si può Google per varie risorse sulla creazione di uno. Look up Meyers Singleton per una semplice soluzione di Singleton.

Un approccio diverso è quello di avere una sorta di InputManager Singleton, e questo manager non mancherà di tenere traccia di un elenco di oggetti che dovrebbero informarli di tasti premuti. Questo può essere fatto in vari modi, il più semplice sarebbe qualcosa di simile:

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)
    {
        // ...
    }
};

Naturalmente si sentono liberi di fare più domande se questo non ha senso.

Altri suggerimenti

Quello che ho finito per fare era

Aggiunta:

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

alla classe WorldObject

E bolla l'evento al Car.

    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++;
        }
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top