Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: nolasco281 en 24 Abril 2014, 03:43 am



Título: Problema con arreglo y clases
Publicado por: nolasco281 en 24 Abril 2014, 03:43 am
Hola a todos como estan.

El problema que tengo es que no se como pasar un arreglo por medio de un constructor no si, se podra. la verdad.

como pueden ver creo en el .h pero asi se pasa por medio del constructor?

como digo no tengo idea de como hacerlo. tengo lo siguiente.

Archivo de encabezado

Código
  1. //Clase creaccion del arreglo
  2. # ifndef ARREGLO_H
  3. # define ARREGLO_H
  4. # include <iostream>
  5.  
  6. using namespace std;
  7.  
  8. class Arreglo
  9. {
  10. private:
  11. int tamano;
  12. int arreglo[tamano];
  13.  
  14. public:
  15. Arreglo(int = 0, int =0);
  16.  
  17. //Metodos Get y set
  18. void setTamano(int);
  19. void setArreglo(int);
  20. int getTamano() const;
  21. int getArreglo() const;
  22.  
  23. //Otros metodos
  24. void MostrarArreglo();
  25.  
  26. };
  27. #endif

Archivo de Implementacion

Código
  1. #include "Arreglo.h"
  2.  
  3. Arreglo::Arreglo(int tamano, int arreglo)
  4. {
  5. setTamano(tamano);
  6. setArreglo(arreglo);
  7. }
  8.  
  9. //Metodos Get y set
  10. void Arreglo::setTamano(int tamano)
  11. {
  12. this->tamano = tamano;
  13. }
  14.  
  15. void Arreglo::setArreglo(int arreglo)
  16. {
  17. this->arreglo = arreglo;
  18. }
  19.  
  20. int Arreglo::getTamano() const
  21. {
  22. return this->tamano;
  23. }
  24.  
  25. int Arreglo::getArreglo() const
  26. {
  27. arreglo =  this->arreglo;
  28. }
  29.  
  30. //Otros metodos
  31. /*
  32. void Arreglo::MostrarArreglo()
  33. {
  34. cout << "Ingrese el tama~no del arreglo: ";
  35. cin >> tamano;
  36.  
  37. for(int i = 0; i <= tamano-1; i++)
  38. {
  39. cout << "\nIntroduzca los datos en el arreglo: ";
  40. cin >> arreglo1[tamano];
  41. }
  42.  
  43. cout << "\nEl arreglo ya esta lleno.";
  44. }*/

Gracias a todos por la ayuda.

PD: se me olvidaba me salta el siquiente error y claro por que se que estoy haciendo algo mal en la forma de pasar el arreglo.

Código
  1. [Error] invalid use of non-static data member 'Arreglo::tamano'


Título: Re: Problema con arreglo y clases
Publicado por: eferion en 24 Abril 2014, 08:30 am
Código
  1. private:
  2. int tamano;
  3. int arreglo[tamano];
  4.  

llegados a ese punto... que valor tiene "tamano"?? obviamente es desconocido, luego esa definición está, directamente, mal hecha.

Código
  1. int * arreglo;

Definir el arreglo de esta otra forma ya es otra cosa... además, queda claro que si el tamaño se puede modificar sobre la marcha, lo lógico es que el arreglo sea directamente dinámico, no?? si fuese de tamaño constante no tendría sentido la variable "tamano".

Dado que el arreglo tienes que crearlo de forma dinámica, tendrás que usar "new" y "delete"... su uso no podía ser más simple:

Código
  1. // Creacion
  2. arreglo = new int[tamano];
  3.  
  4. // Destruccion
  5. delete[] arreglo;
  6. arreglo = 0;

En cualquier caso, debes fijarte en que, por su condición de arreglo, automáticamente pasas a usar punteros... cosa que no estás teniendo en cuenta ni en el constructor ni en "SetArreglo".

Un comentario sobre el diseño:
--------------------------
Vas a empezar a usar memoria dinámica en esta clase, tienes que tener, por tanto, muy claros los ciclos de vida de dicha memoria... dicho de otra forma:

* Cuándo se va a reservar la memoria?
* Cuándo deja de ser necesaria?
* Quién se encarga de liberarla?

Cada vez que tu llames a "SetArreglo", si no controlas bien el ciclo de vida, vas a dejar lagunas de memoria en el programa... y eso queda francamente feo. Además, deberías ir pensando en implementar el destructor.

Lo más lógico es que "Arreglo" se encargue de la gestión de la memoria... es decir, si no le pasas un arreglo entonces el crea uno internamente con el tamaño pedido... cada vez que se llama a "SetArreglo" se ha de eliminar el arreglo anterior... y, por supuesto, si se destruye la instancia, se ha de liberar la memoria reservada por "arreglo".
--------------------------

Un saludo.


Título: Re: Problema con arreglo y clases
Publicado por: nolasco281 en 24 Abril 2014, 09:45 am
Hola primera mente gacias por contestar.

1. Eso quiere decir que debo declarar un puntero para apuntar a mi arreglo
Código
  1. int * arreglo;

y ese puntero es el que pasare como parametro al constructor y al metodo getArreglo.

2. La implementacion del arreglo la hare donde le valla a dar su tama~no no? por ejemplo:

//Funcion para datos del arreglo

Código
  1. tipo funcion ()
  2. {
  3.       //Creacion
  4.       arreglo = new int[tamano];
  5.  
  6.       //Dando un tamano al arreglo
  7.  
  8.       //Liberando memoria
  9.       // Destruccion
  10.          delete[] arreglo;
  11.           arreglo = 0;
  12. }

3. por ultimo el arreglo lo pasaria al constructor de esta forma? al igual en el setArreglo

Código
  1. Arreglo::Arreglo(int tamano, int *arreglo)
  2.  

Si tienes razon el arreglo debe de ser dinamico para poder pasarse, segun el leido en algunas partes, si se le dara un tama~no al arreglo

Muchas gracias por contestar.

PD:No he podido logralo por mi cuenta.


Título: Re: Problema con arreglo y clases
Publicado por: eferion en 24 Abril 2014, 09:56 am
Código
  1. Arreglo::Arreglo(int tamano, int* arreglo)
  2. {
  3.  this->arreglo = 0;
  4.  
  5.  SetArreglo( tamano, arreglo );
  6. }
  7.  
  8. Arreglo::~Arreglo( )
  9. {
  10.  delete[] arreglo;
  11. }
  12.  
  13. //Metodos Get y set
  14. void Arreglo::setTamano(int tamano)
  15. {
  16.  if ( tamano != this->tamano )
  17.  {
  18.    this->tamano = tamano;
  19.  
  20.    delete[] arreglo;
  21.    arreglo = new arreglo[ tamano ];
  22.  }
  23. }
  24.  
  25. void Arreglo::setArreglo( int tamano, int* arreglo )
  26. {
  27.  if ( this->arreglo != 0 )
  28.    delete[] this->arreglo;
  29.  
  30.  this->arreglo = arreglo;
  31.  this->tamano = tamano;
  32. }
  33.  
  34. int Arreglo::getTamano() const
  35. {
  36.  return tamano;
  37. }
  38.  
  39. int* Arreglo::getArreglo() const
  40. {
  41.  return arreglo;
  42. }


Título: Re: Problema con arreglo y clases
Publicado por: nolasco281 en 24 Abril 2014, 10:16 am
1. Entiendo el arreglo que se crea en el construstrutor lo destruye con el destructor no?

Código
  1. Arreglo::~Arreglo( )
  2. {
  3. delete[] arreglo;
  4. }


Esta es la validacion que de la habla, esa parte la entendi
Código
  1.  if ( tamano != this->tamano )
  2. {
  3.   this->tamano = tamano;
  4.   delete[] arreglo;
  5.   arreglo = new arreglo[ tamano ];
  6. }

que tambien se podria hacer asi no

Código
  1. this->tamano = (tamano >0 ? tamano:10) //tama~no defecto

creo que entiendo, todo lo que has hecho pero si me surge una duda la hare saber ya que antes habia intentado hacer algo parecido pero casi no entendia como hacerlo, ahora se me hace un poco mas claro.

Muchas gracias por la ayuda intentare sequir.

Pd: Muchisimas gracias.


Título: Re: Problema con arreglo y clases
Publicado por: eferion en 24 Abril 2014, 10:27 am
Tienes que tener en cuenta que, como has observado, el código que he puesto no hace ninguna comprobación que verifique que el arreglo es válido o que se especifica un tamaño válido.

Esta clase puede evolucionar bastante, pero eso ya depende de tus necesidades.

Pd.: Si en vez de arreglos son clases, una forma sencilla de asegurarte de que te pasan valores válidos es hacer que la función trabaje por referencia... no se pueden pasar referencias no válidas salvo que se hagan chapuzas adrede:

Código
  1.  
  2. class POO
  3. {
  4.  public:
  5.    int Valor( ) { return 1; }
  6. };
  7.  
  8. void Func( POO& clase )
  9. {
  10.  cout << clase.Valor( );
  11. }
  12.  
  13. int main( )
  14. {
  15.  POO* clase = 0;
  16.  
  17.  // Error en tiempo de ejecucion
  18.  Func( &clase );
  19.  
  20.  clase = new POO( );
  21.  
  22.  // ok
  23.  Func( &clase );
  24.  
  25.  delete clase;
  26.  
  27.  // Esto es peligroso con punteros o referencias
  28.  // Lo mejor que te puede pasar es un error en tiempo de ejecucion.
  29.  Func( &clase );
  30. }


Título: Re: Problema con arreglo y clases
Publicado por: nolasco281 en 24 Abril 2014, 10:35 am
 ;-) simplemente

Mil gracias

ha una ultima cosa

en esta parte

Código
  1. // Error en tiempo de ejecucion
  2. Func( &clase );

es de ejecucion o de compilacion.

ya que me dice

Código
  1. [Error] invalid initialization of non-const reference of type 'POO&' from an rvalue of type 'POO**'


Pd: perdon creo que ya entendi : ) por que. o no.
Gracias saludos


Título: Re: Problema con arreglo y clases
Publicado por: eferion en 24 Abril 2014, 10:40 am
;-) simplemente

Mil gracias

ha una ultima cosa

en esta parte

Código
  1. // Error en tiempo de ejecucion
  2. Func( &clase );

es de ejecucion o de compilacion.

ya que me dice

Código
  1. [Error] invalid initialization of non-const reference of type 'POO&' from an rvalue of type 'POO**'

Gracias saludos

cierto... me confundí de carácter... cosas de escribir desde el movil.

Tendría que ser Func( *clase );


Título: Re: Problema con arreglo y clases
Publicado por: nolasco281 en 24 Abril 2014, 10:45 am
Gracias de nuevo por la ayuda por porcionada. y por el tiempo.

y entendi por que la salida es 111.

Saludos y gracias.

Pd:Gracias por los ejemplos tambien. saludos.


Título: Re: Problema con arreglo y clases
Publicado por: eferion en 24 Abril 2014, 10:51 am
La salida da 111 porque devuelvo un valor constante... si accediese a miembros el resultado habría sido muy diferente.

A ver, esta versión si debería dar los problemas que comento... estoy con el movil y no puedo compilar. Si ves algún problema avísame.

Código
  1. #include <iostream>
  2.  
  3. class POO
  4. {
  5.   int variable;
  6.  
  7.  public:
  8.    POO( ) : variable( 1 )
  9.    { }
  10.  
  11.    int Valor( ) { return variable; }
  12. };
  13.  
  14. void Func( POO& clase )
  15. {
  16.  std::cout << clase.Valor( );
  17. }
  18.  
  19. int main( )
  20. {
  21.  POO* clase = 0;
  22.  
  23.  // Error en tiempo de ejecucion
  24.  Func( *clase );
  25.  
  26.  clase = new POO( );
  27.  
  28.  // ok
  29.  Func( *clase );
  30.  
  31.  delete clase;
  32.  
  33.  // Esto es peligroso con punteros o referencias
  34.  // Lo mejor que te puede pasar es un error en tiempo de ejecucion.
  35.  Func( *clase );
  36. }


Título: Re: Problema con arreglo y clases
Publicado por: nolasco281 en 24 Abril 2014, 11:05 am
efectiva mente se produce un error.

(http://4.bp.blogspot.com/-ZKypA5ZPmAk/U1jTugqYB8I/AAAAAAAAAr8/sxxqtffsHs8/s1600/Error.png)

Y luego sique su ejecucion.