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 - X3R4CK3R

#31
jaja, que va, se me da muy mal eso de los discursos, si me he tirado una hora para escribir eso sobre la marcha, gracias! :)
#32
Tampoco hay que ser tan exigente, serán solo una gorra y una dirección de correo, pero, al menos para mí, no es una gorra cualquiera que puedas comprar y ya, sino que simboliza el haber desarrollado algo bueno y que ha gustado a la gente, un trofeo en reconocimiento a ello, al igual que tampoco es una dirección de correo cualquiera, pertenece al dominio elhacker.net, uno de los foros más antiguos y serios de hacking, para mí, el foro donde inicié, en 2008, mi camino hacia C++ sin tener apenas idea previa de programación y donde, con el tiempo, fui aprendiendo  a la vez que ayudaba a quien podía y aportaba códigos de pequeños juegos en consola. El hecho de tener un correo con éste dominio, para mí es un honor y algo de lo que puedo sentirme orgulloso.

Un saludo
#33
Pues bueno, ya terminó la votación, supongo que ahora faltan las menciones para decidir el resultado final.

Enhorabuena a kub0x y WarZ0n3 por el 3º y 2º puesto provisional, y a mí mismo, lol, que si no me equivoco, es definitivo, al tener más del 10% de votos que el 2º puesto, no? :rolleyes:

Espero impaciente los resultados finales, la verdad, no esperaba que mi aplicación fuese la más votada y esto me motiva a seguir desarrollando nuevos proyectos, muchas gracias a todos y saludos!  :)

#34
@amchacon: mm, cierto, no recordaba eso del constructor copia, eso era lo que no encajaba en mi teoría, lo que no entiendo es el orden en el que se van copiando y destruyendo los elementos, pero bueno, supongo que dependerá de los bloques de memoria que hayan libres y tal, así que mejor no darle más vueltas. :laugh: Gracias por la aclaración.

@0xDani: Sí, gracias, aunque la verdad es que ya había pensado en ese método, pero antes de desarrollarlo quise dar un paso más y hacerlo de forma más directa, suelo darle muchas vueltas a todo para hacerlo de la forma más eficiente posible. De cualquier forma, el método funciona y puedo trabajar con él.

Gracias a ambos y un saludo!  ;)
#35
Cita de: amchacon en 15 Julio 2013, 16:34 PM
Los mensajes del destructor no vienen del push_back sino de los delete que has puesto.

No, me refiero a los siguientes:
Citar
Ha nacido Juan.
Ha nacido Lucas.
Ha nacido Antonio.
---
Juan ha sido adoptado. (push_back(c1))
---
Lucas ha sido adoptado. (push_back(c2))
Ha muerto Juan. (c1 muere por push_back(c2))
---
Antonio ha sido adoptado. (push_back(c3))
Ha muerto Juan. (c1 muere por push_back(c3))
Ha muerto Lucas. (c2 muere por push_back(c3))
---
Hijo #0: Juan
Hijo #1: Lucas
Hijo #2: Antonio
Ha muerto Lucas. (Muerte por delete)
Ha muerto Antonio. (Muerte por delete)
Hijo #0: Juan
Hijo #1: Lucas
Hijo #2: Antonio
---
Ha muerto Juan.
Ha muerto Lucas.
Ha muerto Antonio.

Ahí no hay ningún delete. :huh:




Por otra parte, ya he logrado mi propósito y quiero publicar a continuación el código para compartirlo:

class.hpp
Código (cpp) [Seleccionar]
#include <iostream>
#include <vector>
using namespace std;

class Father;

class Child
{
   string name;
   Father *p;
public:
   Child(string);
   ~Child();
   string getName();
   void assignFather(Father *);
};

class Father
{
   vector<Child*> children;
public:
   void addChild(Child *);
   void removeChild(Child *);
   void showNames();
};


class.cpp
Código (cpp) [Seleccionar]
#include "class.hpp"

Child::Child(string n) : name(n)
{
   cout << "Ha nacido " << name << "." << endl;
}

Child::~Child()
{
   cout << "Ha muerto " << name << "." << endl;
   p->removeChild(this);
}

string Child::getName()
{
   return name;
}

void Child::assignFather(Father *p)
{
   this->p = p;
}

void Father::addChild(Child *c)
{
   c->assignFather(this);
   children.push_back(c);
   cout << c->getName() << " ha sido adoptado." << endl;
}

void Father::removeChild(Child *c)
{
   for(unsigned int i=0; i<children.size(); i++)
   {
       if(c==children.at(i))
       {
           children.erase(children.begin()+i);
           cout << "Hijo #" << i << " (" << c->getName() << ") ha muerto." << endl;
           break;
       }
   }
}

void Father::showNames()
{
   cout << "---" << endl
        << "Numero de hijos: " << children.size() << endl;
   for(unsigned int i=0; i<children.size(); i++)
   {
       cout << "Hijo #" << i << ": " << children.at(i)->getName() << endl;
   }
   cout << "---" << endl;
}


main.cpp
Código (cpp) [Seleccionar]
#include "class.hpp"

int main()
{
   Child *c1, *c2, *c3;
   c1 = new Child("Juan");
   c2 = new Child("Lucas");
   c3 = new Child("Antonio");

   Father f1;

   f1.addChild(c1);
   f1.addChild(c2);
   f1.addChild(c3);

   f1.showNames();

   delete c2;

   f1.showNames();

   return 0;
}


Output:
CitarHa nacido Juan.
Ha nacido Lucas.
Ha nacido Antonio.
Juan ha sido adoptado.
Lucas ha sido adoptado.
Antonio ha sido adoptado.
---
Numero de hijos: 3
Hijo #0: Juan
Hijo #1: Lucas
Hijo #2: Antonio
---
Ha muerto Lucas.
Hijo #1 (Lucas) ha muerto.
---
Numero de hijos: 2
Hijo #0: Juan
Hijo #1: Antonio
---

La utilidad de este código puede ser amplia, en mi caso, estoy desarrolando una Gui para SFML, donde un elemento o Widget(Button, TextBox...) sería la clase hijo y una capa(Layout), la clase padre, que contiene el vector de Widgets.

Un saludo
#36
Cita de: amchacon en 15 Julio 2013, 16:04 PMEl problema esque estás creando copiando los objetos cada vez que haces push_back, por eso al hacer esto:

Código (cpp) [Seleccionar]
delete c2;
delete c3;


No tiene ningún efecto, tienes que usar punteros para apuntar a estos objetos:

Código (cpp) [Seleccionar]
vector<Child*> children;
Cita de: X3R4CK3R en 15 Julio 2013, 15:16 PMMientras creaba este post, me he dado cuenta de que estaba haciendo un vector de Hijos (vector<Child>), cuando lo que quería hacer es un vector de punteros a clases Hijos (vector<Child*>).
Sí, lo sé, fue solo un descuido, ya corregí el código antes de postearlo, pero no consideré conveniente postear el código actualizado, ya que la duda que me ha surgido ocurre cuando los elementos no son punteros, todos los elementos (no punteros) se destruyen automáticamente al llegar al final del bracket '}' donde se encuentra declarado, pero ¿por qué al hacer un push_back, el resto de elementos que ya estaban en el vector son destruídos? o al menos, la función destructor es ejecutada. No lo entiendo. :/

Me da la impresión de que no me estoy explicando bien, pero no sé como explicarlo mejor, no es algo que necesite resolver, pero es una duda que me desconcierta y quiero aclarar.  :rolleyes:

Cita de: 0xDani en 15 Julio 2013, 15:53 PM
Claro, lo ideal es que tengas un vector de punteros a los hijos.

En cuanto a esto:

Lo que puedes hacer es que, al incluir un hijo en la lista, el padre notifique al hijo de que ha sido adoptado, y este guarde la dirección de su padre. Luego, al ser destruido el hijo, que llame a una funcion removeChild() (que habrás de implementar, y que eliminará a un hijo de la lista) con su propia dirección.

A mí se me había ocurrido algo parecido:
Al llamar a Father.addChild, guardar en el hijo adoptado la dirección del vector de hijos (miembro de la clase Father), y simplemente, cuando un hijo sea borrado, llamar a la función erase del vector, sería un método directo y muy eficaz, el problema está en hacer un puntero al vector, de primera mano no se me ocurre como hacerlo, he probado con templates pero nada... supongo que tendré que dar algún rodeo y hacerlo como bien has dicho.

Gracias a ambos, un saludo! :)
#37
Buenas, repasando el tema de los destructores me he topado con un bache, algo que intuyo que es provocado por std::vector, me explico:

Tengo una clase "Padre" con un vector de clases "Hijos", cada clase Hijo tiene un destructor que indica la "muerte" de ésta. A partir del código que publico a continuación, esperaba que ningún hijo muriese a no ser que le aplique un delete o el programa finalizase, pero no es así.
Cada vez que hago un push_back a un Hijo desde la clase Padre, los Hijos que ya habían anteriormente en el vector son destruidos, ¿por qué?  :huh:

Mirando la documentación oficial de std::vector::push_back, me encuentro con:

CitarThis effectively increases the container size by one, which causes an automatic reallocation of the allocated storage space if -and only if- the new vector size surpasses the current vector capacity.

Por lo que entiendo de ahí, el hecho de reubicar memoria, podría causar que se destruya la clase Hijo del vector y se vuelva a construir, pero si así fuese, ¿por qué no se ejecuta el cout que notifica que ha nacido la clase Hijo?


class.hpp
Código (cpp) [Seleccionar]
#include <iostream>
#include <vector>
using namespace std;

class Child
{
   string name;
public:
   Child(string);
   ~Child();
   string getName();
};

class Father
{
   vector<Child> children;
public:
   void addChild(Child*);
   void showNames();
};


class.cpp
Código (cpp) [Seleccionar]
#include "class.hpp"

Child::Child(string n) : name(n)
{
   cout << "Ha nacido " << name << "." << endl;
}

Child::~Child()
{
   cout << "Ha muerto " << name << "." << endl;
}

string Child::getName()
{
   return name;
}

void Father::addChild(Child *c)
{
   cout << c->getName() << " ha sido adoptado." << endl;
   children.push_back(*c);
}

void Father::showNames()
{
   for(unsigned int i=0; i<children.size(); i++)
   {
       cout << "Hijo #" << i << ": " << children.at(i).getName() << endl;
   }
}


main.cpp
Código (cpp) [Seleccionar]
#include "class.hpp"

int main(int argc, char *argv[])
{
   Child *c1, *c2, *c3;
   c1 = new Child("Juan");
   c2 = new Child("Lucas");
   c3 = new Child("Antonio");

   Father f1;

   cout << "---" << endl;
   f1.addChild(c1);
   cout << "---" << endl;
   f1.addChild(c2);
   cout << "---" << endl;
   f1.addChild(c3);
   cout << "---" << endl;

   f1.showNames();

   delete c2;
   delete c3;

   f1.showNames();

   cout << "---" << endl;
   return 0;
}


Output
CitarHa nacido Juan.
Ha nacido Lucas.
Ha nacido Antonio.
---
Juan ha sido adoptado.
---
Lucas ha sido adoptado.
Ha muerto Juan.
---
Antonio ha sido adoptado.
Ha muerto Juan.
Ha muerto Lucas.
---
Hijo #0: Juan
Hijo #1: Lucas
Hijo #2: Antonio
Ha muerto Lucas.
Ha muerto Antonio.
Hijo #0: Juan
Hijo #1: Lucas
Hijo #2: Antonio
---
Ha muerto Juan.
Ha muerto Lucas.
Ha muerto Antonio.

Mientras creaba este post, me he dado cuenta de que estaba haciendo un vector de Hijos (vector<Child>), cuando lo que quería hacer es un vector de punteros a clases Hijos (vector<Child*>).
Ésto soluciona el programa que arriba expongo, pero sigo con la duda de por qué, si no es un vector de punteros, ocurre lo arriba explicado.

Aparte de esta duda, una de las metas de éste código es que al hacerle delete a una clase Hijo, ésta sea borrada del vector<Hijos> de la clase Padre, cosa que creo que no es posible hacer directamente, (o tal vez sí, por eso pregunto), de no ser posible, agradecería cualquier método de "actualización", "verificación" o similar, que detecte que un miembro del vector de punteros ha sido borrado, y también debe ser borrado del vector... No sé si me explico. :X

Saludos
#38
Cita de: Caster en 13 Julio 2013, 23:31 PM
libgcc_s_dw2-1.dll y mingwm10.dll.

Saludos

Que extraño, precisamente son esas las dos librerías que incluí en el fixed. :-\
#39
Cita de: Caster en 13 Julio 2013, 21:41 PM
A mi me sigue dando error de que faltan las dos líbrerías pero ya se abre una consola para el server.

Saludos

Dime que librerías son, así las tengo en cuenta para la próxima.

Saludos
#40
Cita de: OmarHack en 13 Julio 2013, 18:45 PM
No es por mal pero eso es injusto para el resto de aplicaciones restantes. Yo sin modificar el código nada de nada puedo añadirle las funcionalidades que quiera. Se que no es tu caso, pero muchos nos pasamos 2 o 3 días creando temas para que nos ayudaran a testear la aplicación, crear máquina virtuales etc para que el programa funcionara sin problemas.

Quitando eso enhorabuena por el programa es muy bueno, yo también estoy haciendo un cifrado para el mio.
Un saludo.

Lo resubí para que gente interesada en el programa lo pudiese ejecutar correctamente, no para que funcionase mejor y facilitarme unos votos, el fichero que está en el hilo oficial sigue teniendo los defectos mencionados, y es esa la aplicación que debería y merece ser votada, ya que es la única presentada dentro de la fecha.

Aún así reconozco que tienes razón y pido disculpas por los problemas que pueda ocasionar.

Gracias y saludos