2012-06-08 35 views
9

Fondamentalmente ciò che voglio fare è memorizzare il riferimento all'animazione attiva di uno sprite come membro privato nella classe attore. Voglio usare un riferimento quindi non devo creare effettivamente l'animazione più volte ma continuo a ricevere un errore.Membro di riferimento non inizializzato

Attore dichiarazione di classe:

class Actor 
{ 
public: 
     Actor(); 
     ~Actor(); 
     void setActiveAnimation(Animation anim); 
     void draw(sf::RenderWindow& win); 

private: 
     sf::Sprite sprite; 
     MaJR::Animation& activeAnimation; 
}; 

implementazione della classe Attore:

Actor::Actor() 
{ 
    // constructor 
} 

Actor::~Actor() 
{ 
    // destructor 
} 

void Actor::setActiveAnimation(Animation anim) 
{ 
    activeAnimation = anim; 
    activeAnimation.gotoStart(); 
} 

void Actor::draw(sf::RenderWindow& win) 
{ 
    sprite.setTexture(activeAnimation.getActiveFrame()); 
    win.draw(sprite); 
    activeAnimation.nextFrame(); 
} 

uscita Corporatura:

/home/mike/MaJR Game Engine/src/Actor.cpp||In constructor 'MaJR::Actor::Actor()':| 
/home/mike/MaJR Game Engine/src/Actor.cpp|8|error: uninitialized reference member 'MaJR::Actor::activeAnimation' [-fpermissive]| 
||=== Build finished: 1 errors, 0 warnings ===| 

risposta

18

Un riferimento non può essere riassegnati, quindi deve essere inizializzato a il membro -inizializzazione-lista. Tuttavia, hai intenzione di riassegnarlo, quindi quello che vuoi non è un riferimento. Inoltre, nella tua funzione setActiveAnimation stai impostando tale riferimento su una copia del valore passato come argomento, che ti lascia un riferimento non valido quando il codice esce dalla funzione. Forse un puntatore ti andrebbe bene?

Nel corpo classe:

MaJR::Animation* activeAnimation; 

E la funzione setActiveAnimation:

void Actor::setActiveAnimation(Animation* anim) 
{ 
    activeAnimation = anim; 
    activeAnimation->gotoStart(); 
} 
+3

L'analisi è buona, ma non posso revocare una risposta con codice che memorizza l'indirizzo di un parametro passato per riferimento. Se si sta memorizzando un puntatore per uso futuro, accettare un parametro puntatore, per rendere il chiamante più consapevole delle considerazioni sulla durata. –

+0

@Ben Voigt: non saprei, non uso affatto _raw pointers_ nel mio codice. –

+1

Sono d'accordo sul fatto che un puntatore raw non è buono come un puntatore intelligente. Ma un riferimento è molto peggio. +1 per la correzione. –

1

È necessario associare un riferimento al momento della definizione. Per i riferimenti dei membri questo significa nella lista di inizializzazione del costruttore. Inoltre l'associazione non può essere riassegnata dopo la dichiarazione.

Se non si dispone dell'oggetto (per ottenere il riferimento a) al momento di installazione degli oggetti Actor, la prossima soluzione migliore consiste nell'utilizzare i puntatori che possono essere riassegnati successivamente in base alle esigenze.

6

Quando si dispone di un membro della classe che è un riferimento, è necessario inizializzarlo nel costruttore. Una volta inizializzato, non puoi più cambiarlo (beh, puoi cambiare il valore ma non dove si riferisce).

Rendi invece attivoAnimazione un puntatore.

2

Non è possibile dichiarare un riferimento non inizializzato. Ciò significa che è necessario inizializzare il riferimento quando si crea un oggetto dalla classe Actor o non è possibile utilizzare un riferimento. Se è necessario cambiarlo in modo dinamico, è possibile utilizzare un puntatore o, probabilmente, un puntatore intelligente (ad esempio std::unique_ptr, shared_ptr). Se non puoi usare C++ 11, dai un'occhiata a smart pointers da Boost.

Problemi correlati