Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - xRodak

#1
Muchisisisimas Gracias !

La verdad es que cambié un poco el sistema. Lo dejé un poco más ordenado. Declaré mi variable en otro hpp, y lo definí en blanco en su respectivo cpp. Haciendo esto obtenía el mismo problema, pero ahora quité el namespace indefinido y mágicamente funcionó. La verdad es que aún no entiendo porqué no funciona utilizando un namespace indefinido, pero al menos pude corregir el error.

Gracias por tu respuesta compañero, independientemente del origen del error, estoy contento de haber podido solucionarlo.
#2
Hola ! Tengo un pequeño problema con la utilización de cierta variable global, les comento lo que tengo y el error que poseo:

Quiero crear una variable 'mMonsterData' global, que sea modificada en la clase World, y que la clase Monster pueda tener accedo a esa información modificada de la variable.

Monster.hpp

struct MonsterData;

class Monster : public Entity
{
    public:
        Monster();
    ......
};

namespace
{
    std::map<Monster::ID, MonsterData*> mMonsterData;
}


DataTables.hpp

struct MonsterData
{
   int                 hitpoints;
   unsigned int                    Type;
   unsigned int                    Size;
   unsigned int                    Element;
};


World.hpp

...
#include <Monster.hpp>
...
...


World.cpp

...
mMonsterData = Value; //<-- Inicializo mi variable con ciertos valores
...

//Más tarde

Monster(spawn.id, mTextures); // Aquí el error. Ignoren los argumentos.


Monster.cpp

#include <Monster.hpp>
#include <DataTables.hpp>

Monster::Monster(Monster::ID id, const TextureHolder& textures) //Error en el contructor de Monster
: Entity(mMonsterData[id]->hitpoints)  //<-- ERROR: mMonsterData[id]->hitpoints, si cambio esta expresion por un int, el error se corrige.
, mSprite(textures.get(mMonsterData[id]->texture)) // También debería dar error aquí
{

}


El error reside en que, mi variable 'global' modificada en World.cpp, se modificó, pero solo es utilizable en World.cpp. Desde allí puede acceder a mMonsterData[id]->hitpoints u otras de sus variables sin ningún problema. Pero al momento de querer obtener sus datos en el constructor de Monster, la aplicación de cae. Esto es porque mMonsterData aún no es inicializada en este contexto (siendo que debería ser una variable global (?) ).

Ese es mi problema, alguien sabe donde está el error? Cómo puedo hacer que al modificar dicha variable en World.cpp, estos valores modificados puedan ser obtenidos en el Monster.cpp?

Estuve averiguando sobre variables globales, y la keyword 'extern', pero estuve otro tipo de errores haciéndolo de esa manera, así que vamos por parte, primero sus opiniones.

Muchas gracias por leer y también gracias de antemano.

Saludos cordiales.
#3
Gracias por tu respuesta eferion ! Yo pensaba que la enumeración era algo más que un simple int (suponiendo que se utilizan como ints). Por eso pensaba que existía alguna diferencia considerable entre utilizar ambas definiciones. Ahora veo que definir una variable como entero es más adecuado.

Muchas gracias !

Y yoel, de verdad confundiste mi pregunta xD.

Saludos !
#4
Hola compañeros ! Me entró una duda sobre la definición de ciertas variables.

Supongamos tengo la siguiente enumeración:

namespace ENUM
{
    enum ID
    {
        a,
        b,
        c,
    };
}


Cuál sería una forma correcta de declarar un valor de dicha enumeración?

ENUM::ID       valor = ENUM::a;

o

unsigned int    valor = ENUM::a;

He visto ejemplo donde se utiliza la primera, pero según lo que he alcanzado a estudiar, la segunda sería más ideal.

Cómo sé cual de las dos debo utilizar dependiendo de cierto contexto?

Saludos y gracias de antemano.
#5
Muchas gracias eferion ! Sinceramente me aún me cuesta entender entender un poco lo del shared_ptr y el leak_ptr. Me dedicaré a estudiarlos más a fondo para entender bien su funcionamiento y saber cual debo utilizar para mis objetivos.

Hasta el momento entendi muy bien por qué se pierde la memoria utilizando un unique_ptr. Muchas gracias nuevamente por tu respuesta !

Saludos.
#6
Solucionado !

Después de mucho leer en internet, intenté nuevamente averiguar cuál era el error. Como sospechaba, al crear un Character, este era creado exitosamente, pero al ser devuelto por la funcion getCharacter, su memoría era liberada, por lo que la variable 'character' utilizaba memoria liberada.

Sinceramente, no logro ver el error por mi mismo, sé que el error es gracias a utilizar el std::unique_ptr, pero no logro ver en qué linea o porqué la memoria es liberada al momento de utilizar la función getCharacter.

Si alguien pudiera explicarme esto último le estaría muy agradecido, para no volver a cometer el mismo error a futuro que tanto me costó corregir.

Muchas gracias por leer. Saludos.

PD: Perdón por el doble post, pero era para que la gente que ya vió el tema entre nuevamente para ayudarme con este nuevo error, si lo editaba esas visitas probablemente se perderían al no tener actividad el tema.
#7
A que te refieres con accesos de memoria?

Saludos.
#8
Hola compañeros ! He buscado y buscado acerca del error que poseo, y solo he logrado averiguarque es referente a la inicialización de variables y/o punteros, pero no he logrado corregirlo.

El error que poseo es el siguiente:

std::string::assign(std::string const&) ()

Según tiene que ver con la inicialización de mis clases, por lo que les dejo más o menos lo que poseo:

Account& account = *getContext().account;
account.createCharacter(Professions::Bloodge, *getContext().textures);
Character& character = account.getCharacter(account.getSlot());
character.setName(name); //<------ AQUÍ EL ERROR


Les explico como funciona:

'getContext.account' me regresa un puntero a un objeto Account. Este objeto YA FUE INICIALIZADO por lo que dicho puntero no debería tener fallos.
'account.createCharacter' crea un objeto Character nuevo en la cuenta.
'account.getCharacter' regresa una referencia a dicho personaje creado (la cuenta posee 3 Slots, por lo que se señala cual de los 3 personajes quiero obtener, con el getSlot, que devuelta el Slot actual en el cual estoy creando el personaje, para asegurarme de que obtenga el personaje recien creado, y no una referencia vacía u otro Character de los demás slots, evitando errores)

Guardo la referencia al personaje recién creado en la variable 'character'. Y luego procedo a asignarle un nombre. La variable 'name' contiene un string, no vacio (std::string name;)


Account.hpp

class Account
{
public:
    Account();
    void createCharacter(Professions::ID id, const TextureHolder& textures);
    Character& getCharacter(int n);
private:
    std::array<Character*, MAX_CHARACTERS> mCharacters;    //array que contiene punteros a Character, de tamaño MAX_CHARACTERS
    int currentChars;
    int currentSlot;
};


Account.cpp

Account::Account()
{
    currentChars = 0;
    currentSlot = -1;

    //Aquí señalo que inicialmente todos los punteros a objetos Character, serán punteros nulos, es decir, una cuenta sin personajes (Characters)
    mCharacters[0] = nullptr;
    mCharacters[1] = nullptr;
    mCharacters[2] = nullptr;
}

void Account::createCharacter(Professions::ID id, const TextureHolder& textures)
{
        //crea un nuevo personaje en un puntero
        std::unique_ptr<Character> newCharacter( new Character(id, textures));

        //hace que el array apunte a este nuevo Character creado, para asi guardar el nuevo personaje en la cuenta
        //currentSlot es el Slot en donde estoy creando el personaje, la función getSlot utilizada arriba devuelve este valor.
        mCharacters[currentSlot] = newCharacter.get();

        ++currentChars;

}

Character& Account::getCharacter(int n)
{
    std::cout << "n = " << n << std::endl;

    // retorna un personaje de la cuenta (retorna una referencia)
    return *mCharacters[n];
}


Character.hpp

class Character:
{
    public:
explicit Character(Professions::ID id, const TextureHolder& textures);
void setName(std::string& name);
std::string getName() const;

    private:
        std::string mName;

};


Character.cpp


Character::Character(Professions::ID id, const TextureHolder& textures)
{
}

void Character::setName(std::string& name)          //<------- Esta es la función que da el error
{
    std::cout << "setName activada" << std::endl;
    mName = name;                                              //<------- Esta es la linea del error
    std::cout << "Se dio el nombre con exito" << std::endl; //Obviamente esta linea no se imprime en la consola S:
}


std::string Character::getName() const
{
    return mName;
}




Es bastante código, pero el funcionamiento es super simple y fácil de entender, coloqué todo lo involucrado para que se entienda de donde puede provenir el error.

Espero que puedan ayudarme, estoy bastante desesperado, mucha gracias de antemano !
#9
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 !
#10
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.