2012-06-08 23 views
9

Básicamente lo que quiero hacer es almacenar la referencia a la animación activa de un elemento como miembro privado en la clase Actor. Quiero usar una referencia, así que no tengo que crear la animación muchas veces, pero sigo recibiendo un error.Miembro de referencia no inicializado

Actor declaración de la clase:

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

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

implementación de la clase Actor:

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(); 
} 

resultados de generación:

/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 ===| 

Respuesta

18

Una referencia no puede ser reasignados, por lo que debe ser inicializado en el miembro -inicialización-list. Sin embargo, tiene la intención de reasignarlo, por lo que lo que quiere no es una referencia. Además, en su función setActiveAnimation está estableciendo dicha referencia a una copia del valor pasado como argumento, lo que le deja una referencia no válida cuando el código sale de la función. Tal vez un puntero te conviene?

En el cuerpo de la clase:

MaJR::Animation* activeAnimation; 

Y la función setActiveAnimation:

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

Su análisis es bueno, pero no puedo respaldar una respuesta con código que almacena la dirección de un parámetro pasado por referencia. Si está almacenando un puntero para usarlo más adelante, acepte un parámetro de puntero para que la persona que llama esté más al tanto de las consideraciones de la vida útil. –

+0

@Ben Voigt: No lo sé, no uso _raw puninters_ en mi código. –

+1

Acepto que un puntero sin formato no es tan bueno como un puntero inteligente. Pero una referencia es mucho peor. +1 para la solución. –

1

Es necesario enlazar una referencia al momento de la definición. Para referencias de miembros, esto significa en la lista de inicializadores del constructor. Además, el enlace no puede ser reasignado después de la declaración.

Si no tiene el objeto (para obtener la referencia) en el momento de la instauración de los objetos Actor, su siguiente mejor opción es utilizar punteros que pueden reasignarse posteriormente según sea necesario.

6

Cuando tiene un miembro de su clase que es una referencia, DEBE inicializarlo en el constructor. Una vez que se inicializa, ya no puede cambiarlo (bueno, puede cambiar el valor, pero no a dónde se refiere).

Haga que activeAnimation sea un puntero.

2

No puede declarar una referencia no inicializada. Eso significa que necesita inicializar la referencia cuando crea un objeto de la clase Actor o no puede usar una referencia. Si necesita cambiarlo dinámicamente, puede usar un puntero o, probablemente mejor, un puntero inteligente (p. Ej., std::unique_ptr, shared_ptr). Si no puede usar C++ 11, eche un vistazo a smart pointers de Boost.

Cuestiones relacionadas