• Sábado 14 de Diciembre de 2024, 12:51

Autor Tema:  Clases que llaman a otras clases  (Leído 4667 veces)

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Clases que llaman a otras clases
« en: Martes 10 de Marzo de 2009, 15:06 »
0
la quisiera saber si esto es posible y en ese caso como se haria:

Tengo dos clases, una server y la otra LD. Cada instancia de la clase server puede contener una o mas instancias de LD, la cantidad no es fija. Mi pregunta es como hacer esto? Podria luego desde mi programa principal hacer: instancia_de_server.instancia_de_LD.algun_atributo _de_LD ?? Sería como que la instancia LD dentro del server es luego utilizada en el main como si fuera un atributo mas del server.


Si alguien me puede dar una mano se lo agradezco

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #1 en: Martes 10 de Marzo de 2009, 16:55 »
0
Memoria dinámica con punteros a objetos, esto es:

Código: C
  1. LD *puntero_a_LD;
  2. [...]
  3. puntero_a_LD = new(LD)
  4.  
Así puedes construir una lista dinámica de punteros a objetos LD (o cualquier objeto)

emuller

  • Miembro MUY activo
  • ***
  • Mensajes: 104
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #2 en: Martes 10 de Marzo de 2009, 22:12 »
0
Hola. No recuerdo mucho de C++ pero ahí va:

Además de la solución de m0skit0, también puedes utilizar los vectores de la STL (http://www.cppreference.com/wiki/stl/vector/start) para la lista dinámica de clases LD. La clase server debe tener un atributo de tipo Vector, y dentro de ese vector almacenas, por ejemplo, punteros a objetos LD (recuerda hacer delete al puntero de un objeto LD si vas a borrarlo del Vector, ya que aunque borres el puntero el objeto sigue existiendo y ocupa memoria).

Además, para que tu programa principal pueda acceder a los objetos LD la clase server debe proveerle de algún mecanismo para que pueda acederlos. Hay varias formas, suponiendo que usas un vector:
1) Puedes hacer que el atributo de tipo Vector sea público. En la POO esto no se considera una buena forma de hacerlo.
2) Hacer que el Vector sea privado y colocar un método en la clase server que retorne un puntero a ese vector.
3) Hacer que el Vector sea privado y colocar métodos en la clase server que te permitan obtener los punteros a los objetos LD.
4) y varias más

Espero no haber dicho pavadas y te sirva.
Mi deseo: que le otorguen el premio Nobel de la paz al inventor del Copy & Paste. Gracias por evitarme tantas peleas con el tiempo y aumentar la esperanza de vida de mi teclado \":)\"

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #3 en: Miércoles 11 de Marzo de 2009, 09:47 »
0
Cita de: "emuller"
La clase server debe tener un atributo de tipo Vector, y dentro de ese vector almacenas, por ejemplo, punteros a objetos LD (recuerda hacer delete al puntero de un objeto LD si vas a borrarlo del Vector, ya que aunque borres el puntero el objeto sigue existiendo y ocupa memoria).
Efectivamente, pero te olvidas de que de esta forma también defines un máximo de elementos de forma estática que no puedes modificar a menos que recompiles el programa. Y también que tu método es más rápido que el mío, pero presenta el inconveniente anteriormente mencionado. ¡No se puede tener todo, amigos!  B)

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #4 en: Miércoles 11 de Marzo de 2009, 14:47 »
0
m0squit0 ya me anduvo como me dijiste, la verdad de mucha ayuda, gracias.

emuller

  • Miembro MUY activo
  • ***
  • Mensajes: 104
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #5 en: Miércoles 11 de Marzo de 2009, 15:42 »
0
Cita de: "m0skit0"
Cita de: "emuller"
La clase server debe tener un atributo de tipo Vector, y dentro de ese vector almacenas, por ejemplo, punteros a objetos LD (recuerda hacer delete al puntero de un objeto LD si vas a borrarlo del Vector, ya que aunque borres el puntero el objeto sigue existiendo y ocupa memoria).
Efectivamente, pero te olvidas de que de esta forma también defines un máximo de elementos de forma estática que no puedes modificar a menos que recompiles el programa. Y también que tu método es más rápido que el mío, pero presenta el inconveniente anteriormente mencionado. ¡No se puede tener todo, amigos!  B)

No se si se entendió bien lo que dije, con vector me refería a la clase "vector" de la STL al que parece, según la documentación en  el enlace que coloqué, se lo puede redimensionar. De todas formas sólo lo usé un par de veces de manera muy simple y hace bastante tiempo ya, así que es muy probable que me haya equivocado en la idea.

Gracias por la acotación, siempre se aprende algo nuevo !!  :)
Mi deseo: que le otorguen el premio Nobel de la paz al inventor del Copy & Paste. Gracias por evitarme tantas peleas con el tiempo y aumentar la esperanza de vida de mi teclado \":)\"

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #6 en: Miércoles 11 de Marzo de 2009, 16:00 »
0
Cita de: "emuller"
con vector me refería a la clase "vector" de la STL al que parece
Ah, disculpa la confusión. Pero yo siempre defiendo el HTM (Hazlo Tú Mismo), creo que se aprende más y además se tiene más control sobre qué se está haciendo realmente. Aunque tampoco hay que reinventar la rueda  :)

Salud

emuller

  • Miembro MUY activo
  • ***
  • Mensajes: 104
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #7 en: Miércoles 11 de Marzo de 2009, 22:56 »
0
Cita de: "m0skit0"
... yo siempre defiendo el HTM (Hazlo Tú Mismo), creo que se aprende más y además se tiene más control sobre qué se está haciendo realmente...  

Estoy de acuerdo. Para aprender las bases del lenguaje prefiero hacerlo yo mismo.  :comp:
Mi deseo: que le otorguen el premio Nobel de la paz al inventor del Copy & Paste. Gracias por evitarme tantas peleas con el tiempo y aumentar la esperanza de vida de mi teclado \":)\"

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #8 en: Jueves 12 de Marzo de 2009, 13:05 »
0
Pense que lo habia hecho como me dijiste pero en realidad no, esto hice:

#include "iostream.h"

class LD{
public:
int a;

LD(){cout << "LD creado" << endl;};
~LD(){cout << "LD destruido." << endl;};

};


class Server {
public:
LD *pLD;
Server();
~Server();
void cambioa(int b);
};

Server::Server() {cout << "Server creado" << endl;}
Server::~Server() {cout << "Server destruido." << endl;}
void Server::cambioa(int b)
{
int c;
c=b;
pLD= new LD[c];
pLD[c-1].a=4;
}
 
  int main () {
  Server server;
  server.cambioa(3);
  cout << server.pLD[2].a << endl;
  return 1;
  }



Pero de esta forma el parametro b me fija la cantidad de LD, para hacerlo mas dinamico seria como vos decis pero no me sale. En ese caso, como haria para saber cual es el ultimo LD creado? o sea a partir del puntero como lo referencio??

gracias

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #9 en: Jueves 12 de Marzo de 2009, 13:26 »
0
Solucionado!

Cree el puntero en la clase server, asi el puntero se crea una vez y no se toca mas, sino cada vez que llamaba al metodo el puntero cambiaba, lo que si mosquito en la declaracion tengo dos opciones que funcionan:
pLD= new LD; y pLD= new LD[];
Es lo mismo o me conviene utilizar alguna de las 2??

gracias.

Asi quedo el codigo:

#include "iostream.h"

class LD{
public:
int a;

LD(){cout << "LD creado" << endl;};
~LD(){cout << "LD destruido." << endl;};

};


class Server {
public:
LD *pLD;
Server();
~Server();
void cambioa(int b);
};

Server::Server()
{
cout << "Server creado" << endl;
pLD= new LD;
}
Server::~Server() {cout << "Server destruido." << endl;}
void Server::cambioa(int b)
{
int c;
c=b;
pLD[c].a=c;
}
 
  int main () {
  Server server;
  server.cambioa(0);
  server.cambioa(1);
  cout << server.pLD[0].a << endl;
  cout << server.pLD[1].a << endl;
  return 1;
  }

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #10 en: Jueves 12 de Marzo de 2009, 13:30 »
0
Cita de: "rgpsolocodigo"
pLD= new LD;
Puntero a 1 objeto de clase LD

Cita de: "rgpsolocodigo"
pLD= new LD[];
Puntero a vector de objetos de clase LD

Por cierto, no olvides usar delete() para liberar la memoria de los objetos que ya no se usen. Un destructor en condiciones es la mejor opción para mantenerse dentro de lo recomendado por POO.

Salud

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #11 en: Jueves 12 de Marzo de 2009, 14:51 »
0
Fijate ese codigo que hice, que si bien creo un objeto LD luego en el main lo uso como si fuera un vector de objetos LD, quizas esta mal hacerlo asi, de todas formas al declararlo LD[] es un vector de cuantos elementos??

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #12 en: Jueves 12 de Marzo de 2009, 16:14 »
0
Cita de: "rgpsolocodigo"
si bien creo un objeto LD luego en el main lo uso como si fuera un vector de objetos LD
Si vas a usar un vector, declara un vector. Si no, pues con un objeto te vale.

Cita de: "rgpsolocodigo"
de todas formas al declararlo LD[] es un vector de cuantos elementos??
En C y en C++ los vectores son simplemente un puntero al inicio de los datos, del resto se tiene que ocupar el programador, ya que C no distingue entre un puntero y un vector. En tu caso omites el número de elementos, por tanto no se reserva memoria para el vector. Si declararas por ejemplo LD[10] pues se resevaría memoria de antemano para 10 elementos sin tener que usar new(). Pero si es LD[], entonces vas a tener que reservar la memoria manualmente.

Salud

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #13 en: Jueves 12 de Marzo de 2009, 19:52 »
0
No me queda del todo claro, en el codigo que adjunto, declaro a mi puntero LD *pLD;, en el constructor de server lo inicializo asi: pLD= new LD[];, despues lo uso como si fuera un vector, le agrego todos los objetos LD que quiero desde algun metodo de server, pero como sabe el compilador que dimension darle? Por ejemplo, server podria tener un metodo para crear LDs de forma un cliente externo podria invocar este metodo y el programa intentaria usar mas elementos de este vector, podria sobreescribir algo de manera incorrecta?

#include "iostream.h"

class LD{
public:
int a;

LD(){cout << "LD creado" << endl;};
~LD(){cout << "LD destruido." << endl;};

};


class Server {
public:
LD *pLD;
Server();
~Server();
void cambioa(int b);
};

Server::Server()
{
cout << "Server creado" << endl;
pLD= new LD[];
}
Server::~Server() {cout << "Server destruido." << endl;}
void Server::cambioa(int b)
{
int c;
c=b;
pLD[c].a=c;
}

int main () {
Server server;
server.cambioa(0);
server.cambioa(1);
cout << server.pLD[0].a << endl;
cout << server.pLD[1].a << endl;

return 1;
}

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #14 en: Viernes 13 de Marzo de 2009, 10:05 »
0
UTILIZA LAS ETIQUETAS DE CÓDIGO

Cita de: "rgpsolocodigo"
declaro a mi puntero LD *pLD;, en el constructor de server lo inicializo asi: pLD= new LD[];,
Bueno, como ya te he dicho, es tontería hacerlo así. Con new LD[] lo que haces es crear un puntero a un vector sin elementos, ni siquiera reservas la memoria para ellos (puesto que no has indicado cuántos son. Con new LD tampoco se reserva la memoria del vector, sino un solo objeto. Con new LD[c] sí reservarías espacio para c objetos de clase LD, por ejemplo.

Cita de: "rgpsolocodigo"
despues lo uso como si fuera un vector, le agrego todos los objetos LD que quiero desde algun metodo de server, pero como sabe el compilador que dimension darle?
Como ya te dije, no tiene dimensión. Para poder agregarle objetos de forma segura (para que el sistema operativo no te borre tus datos o no generes excepciones de violación de memoria), primero debes reservar la memoria. Es lo que estás haciendo mal aquí:

Código: C++
  1. void Server::cambioa(int b)
  2. {
  3.     int c;
  4.     c=b;
  5.     pLD[c].a=c;
  6. }
  7.  
No puedes asignar un valor al atributo del objeto pLD[c] porque éste no existe. Así que o bien declaras con anterioridad pLD = new LD[numero_de_objetos], o bien lo haces cada vez que vayas a insertar uno nuevo, para lo que debes llevar la cuenta de los objetos:

Código: C++
  1. void Server::cambioa(int b)
  2. {
  3.     int c;
  4.     c=b;    
  5.     pLD[c] = new LD;
  6.     pLD[c].a=c;
  7. }
  8.  
Todo esto sin olvidar hacer un delete a todos los objetos creados con new en el destructor de la clase LD.

Ánimo

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #15 en: Viernes 13 de Marzo de 2009, 17:14 »
0
No se como poner el codigo como lo pones vos, bueno lo pongo en negrita.

Esto es lo que me recomendaste:

void Server::cambioa(int b)
{
    int c;
    c=b;    
    pLD[c] = new LD;
    pLD[c].a=c;
}



pero asi, previamente tengo que declarar a pLD con dimensiones fijas, no puedo agreegarle elementos de forma dinamica. A lo mejor quiero hacer algo que no es posible, de ultima declaro *pLD de dimension 100 ponele y no uso todos los elementos, que otra forma podria utilizar?

gracias

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #16 en: Lunes 16 de Marzo de 2009, 09:34 »
0
Cita de: "rgpsolocodigo"
pero asi, previamente tengo que declarar a pLD con dimensiones fijas, no puedo agreegarle elementos de forma dinamica.
¿Te da algún error el compilador o qué? Ponlo por favor.

rgpsolocodigo

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Clases que llaman a otras clases
« Respuesta #17 en: Lunes 16 de Marzo de 2009, 15:22 »
0
MM, en visual ningun problema, pero cuando intente compilar con gcc me tiro un monton de errores, lo voy a hacer en forma estatica definiendo un vector en vez de un puntero y dandole una dimension fija, de todos modos gracias

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Clases que llaman a otras clases
« Respuesta #18 en: Lunes 16 de Marzo de 2009, 16:03 »
0
Cita de: "rgpsolocodigo"
lo voy a hacer en forma estatica definiendo un vector en vez de un puntero y dandole una dimension fija,
Bueno, como ya te dije, un vector es un puntero. Lo que no termino de entender es que pLD[c].a=c; te funcione a secas y cuando le añadas pLD[c] = new LD; te dé problemas.

Por cierto, siempre tienes la solución de hacerte una lista enlazada y definirle el operador [].

Ánimo y suerte