[Problema] Lista de inicialización de una estrucura..... (Solucionado)

Iniciado por xRodak, 19 Enero 2014, 19:39 PM

0 Miembros y 1 Visitante están viendo este tema.

xRodak

Hola ! Llevo 2 días intentando reparar un error, y creo que ya estoy muy cerca de lograrlo, pero ya no doy más, así que les pido ayuda.

Sucede que tengo los siguientes errores

|323|error: expected class-name before '(' token
|323|error: expected '{' before '(' token
|324|error: expected constructor, destructor, or type conversion before ',' token
|324|error: expected constructor, destructor, or type conversion before '(' token


(El problema se presenta en la clase State, en la estructura Context, y en sus respectivos contructores, así que pueden ignorar el resto de las clases que desconozcan, las puse para que se entienda de qué trata el código.)

Mi código es de este estilo:

class State
{

   public:
       struct Context
       {
           //Constructor
           Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player);
           sf::RenderWindow* window;
           TextureHolder* textures;
           FontHolder* fonts;
           Player* player;
       };

   public:
       State(StateStack& stack, Context context);
       virtual ~State();
   private:
       Context mContext;
};


//Constructor de la estructura Context que está dentro de la clase State
//Este contructor debería guardar referencias (o punteros) a los recursos obtenidos por argumento
State::Context::Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player)
//Lista de inicialización
: State::Context::window(window)                        //Linea 323
, State::Context::textures(textures)                        //Linea 324
, State::Context::fonts(fonts)
, State::Context::player(player)
{

}

State::State(StateStack& stack, State::Context context)
//Lista de inicialización 2, llama al constructor de Contexto
: mContext(State::Context(*(context.window),*(context.textures),*(context.fonts),*(context.player)))
{

}


Según lo que tengo entendido, la lista de inicialización del contructor de Context debería estar correcta, pero ambas en conjuntos me entra la duda. Podría alguien decirme donde está el error en las listas de inicialización, o si debo utilizar otra forma para resolver el problema?

Muchas gracias de antemano.

amchacon

El parametro window es un objeto, pero en la estructura lo tienes declarado como un puntero. Lo mismo con las texturas y las fuentes.

Mi consejo esque cambies los punteros por referencias:
Código (cpp) [Seleccionar]
struct Context
{
   //Constructor
   Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player);
   sf::RenderWindow& window;
   TextureHolder& textures;
   FontHolder& fonts;
   Player& player;
};


Eso si debería irte, también puedes dejarlos como punteros y hacer esto:

Código (cpp) [Seleccionar]
State::Context::Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player)
//Lista de inicialización
: State::Context::window(&window)
, State::Context::textures(&textures)
, State::Context::fonts(&fonts)
, State::Context::player(&player)
{

}


Pero son bastantes más comodas las referencias, te olvidas poner el * o los -> cada vez que vayas a usarlo.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

xRodak

Gracias por el consejo,  lo arreglaré apenas solucione el problema principal.

Ya pude avanzar algo con el problema, lo que sucede ahora, es que, no sé como llamar al constructor de la estructura interior. El códido que tengo es el siguiente:

class State
{
    public:
        typedef std::unique_ptr<State> Ptr;
        struct Context
        {
            Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player);
            sf::RenderWindow* window;
            TextureHolder* textures;
            FontHolder* fonts;
            Player* player;
        }Nested;

    public:
        State(StateStack& stack, Context context);
        virtual ~State();
        virtual void draw() = 0;
        virtual bool update(sf::Time dt) = 0;
        virtual bool handleEvent(const sf::Event& event) = 0;
    protected:
        void requestStackPush(States::ID stateID);
        void requestStackPop();
        void requestStateClear();
        Context getContext() const;
    private:
        StateStack* mStack;
        Context mContext;
};

State::Context::Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player)
:window(&window),
textures(nullptr),
fonts(nullptr),
player(nullptr)
{

}

State::State(StateStack& stack, State::Context context)
//EL ERROR ESTÁ EN ESTA LINEA, DEBO LLAMAR AL CONTRUCTOR DE 'Context' entregando 4 argumentos

//:Context(*(context.window),*(context.textures),*(context.fonts),*(context.player))
//:State::Context(*(context.window),*(context.textures),*(context.fonts),*(context.player))
: Nested(*(context.window),*(context.textures),*(context.fonts),*(context.player))
{

}


He intentado llamar al contructor de diversas formas. El error reside en que el emulador me señala que estoy contruyendo un Context entregando 0 argumentos, en donde me señala que este pide 4 argumentos (claro, así está definido su contructor). Por lo que deduje, que no estoy llamando correctamente  al constructor, por lo que el emulador lo llama automaticamente entregándole 0 argumentos.

Alguien sabe como llamo al contructor de al estructura interior Context desde el contructor de State?

amchacon

Código (cpp) [Seleccionar]
State::State(StateStack& stack, State::Context context)

Pasa ese context por referencia y usa el constructor copia para inicializar tu Context:

Código (cpp) [Seleccionar]
State::State(StateStack& stack, State::Context &context) : mContext(context)
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

xRodak

Edito.

Ya estoy viendo la luz, había confundido una nested class con herencia. No necesitaba un inicializador para mi caso. Lo solucioné de la forma que me mencionaste, pero haciendo otr pequeño cambio. Ahora tengo un nuevo problema, no sé a que refiere, busqué en google pero no encontré mucho.

Este es mi nuevo código y el nuevo error:

class State
{
    public:
        typedef std::unique_ptr<State> Ptr;
        struct Context
        {
            Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player);
            sf::RenderWindow* window;
            TextureHolder* textures;
            FontHolder* fonts;
            Player* player;
        };

    public:
        State(StateStack& stack, Context context);
        virtual ~State();
        virtual void draw() = 0;
        virtual bool update(sf::Time dt) = 0;
        virtual bool handleEvent(const sf::Event& event) = 0;
    protected:
        void requestStackPush(States::ID stateID);
        void requestStackPop();
        void requestStateClear();
        Context getContext() const;
    private:
        StateStack* mStack;
        Context mContext;
};

State::Context::Context(sf::RenderWindow& window, TextureHolder& textures, FontHolder& fonts, Player& player)
:window(&window),
textures(nullptr),
fonts(nullptr),
player(nullptr)
{

}

State::State(StateStack& stack, State::Context context)
: mContext(context)
{

}


In function `ZN5StateC2ER10StateStackNS_7ContextE':|
undefined reference to `vtable for State'|


Gracias por leer y por la ayuda.

amchacon

Código (cpp) [Seleccionar]
State::State(StateStack& stack, State::Context context)
: mContext(context)
{

}


Te dije que pasaras el Context por referencia:

Código (cpp) [Seleccionar]
State::State(StateStack& stack, State::Context &context)
: mContext(context)
{

}


Y en cuanto al error. ¿Seguro que no es un tema de archivos?
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

xRodak

Listo, lo cambié a referencia.

El último error tenia que ver con el destructor virtual de la clase, había olvidado definir el destructor virtual no puro.

Muchas gracias por la ayuda ! Problemas resueltos !