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
//Clase creaccion del arreglo
# ifndef ARREGLO_H
# define ARREGLO_H
# include <iostream>
using namespace std;
class Arreglo
{
private:
int tamano;
int arreglo[tamano];
public:
Arreglo(int = 0, int =0);
//Metodos Get y set
void setTamano(int);
void setArreglo(int);
int getTamano() const;
int getArreglo() const;
//Otros metodos
void MostrarArreglo();
};
#endif
Archivo de Implementacion
#include "Arreglo.h"
Arreglo::Arreglo(int tamano, int arreglo)
{
setTamano(tamano);
setArreglo(arreglo);
}
//Metodos Get y set
void Arreglo::setTamano(int tamano)
{
this->tamano = tamano;
}
void Arreglo::setArreglo(int arreglo)
{
this->arreglo = arreglo;
}
int Arreglo::getTamano() const
{
return this->tamano;
}
int Arreglo::getArreglo() const
{
arreglo = this->arreglo;
}
//Otros metodos
/*
void Arreglo::MostrarArreglo()
{
cout << "Ingrese el tama~no del arreglo: ";
cin >> tamano;
for(int i = 0; i <= tamano-1; i++)
{
cout << "\nIntroduzca los datos en el arreglo: ";
cin >> arreglo1[tamano];
}
cout << "\nEl arreglo ya esta lleno.";
}*/
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.
[Error] invalid use of non-static data member 'Arreglo::tamano'
private:
int tamano;
int arreglo[tamano];
llegados a ese punto... que valor tiene "tamano"?? obviamente es desconocido, luego esa definición está, directamente, mal hecha.
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:
// Creacion
arreglo = new int[tamano];
// Destruccion
delete[] arreglo;
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.
Hola primera mente gacias por contestar.
1. Eso quiere decir que debo declarar un puntero para apuntar a mi arreglo
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
tipo funcion ()
{
//Creacion
arreglo = new int[tamano];
//Dando un tamano al arreglo
//Liberando memoria
// Destruccion
delete[] arreglo;
arreglo = 0;
}
3. por ultimo el arreglo lo pasaria al constructor de esta forma? al igual en el setArreglo
Arreglo::Arreglo(int tamano, int *arreglo)
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.
Arreglo::Arreglo(int tamano, int* arreglo)
{
this->arreglo = 0;
SetArreglo( tamano, arreglo );
}
Arreglo::~Arreglo( )
{
delete[] arreglo;
}
//Metodos Get y set
void Arreglo::setTamano(int tamano)
{
if ( tamano != this->tamano )
{
this->tamano = tamano;
delete[] arreglo;
arreglo = new arreglo[ tamano ];
}
}
void Arreglo::setArreglo( int tamano, int* arreglo )
{
if ( this->arreglo != 0 )
delete[] this->arreglo;
this->arreglo = arreglo;
this->tamano = tamano;
}
int Arreglo::getTamano() const
{
return tamano;
}
int* Arreglo::getArreglo() const
{
return arreglo;
}
1. Entiendo el arreglo que se crea en el construstrutor lo destruye con el destructor no?
Arreglo::~Arreglo( )
{
delete[] arreglo;
}
Esta es la validacion que de la habla, esa parte la entendi
if ( tamano != this->tamano )
{
this->tamano = tamano;
delete[] arreglo;
arreglo = new arreglo[ tamano ];
}
que tambien se podria hacer asi no
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.
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:
class POO
{
public:
int Valor( ) { return 1; }
};
void Func( POO& clase )
{
cout << clase.Valor( );
}
int main( )
{
POO* clase = 0;
// Error en tiempo de ejecucion
Func( &clase );
clase = new POO( );
// ok
Func( &clase );
delete clase;
// Esto es peligroso con punteros o referencias
// Lo mejor que te puede pasar es un error en tiempo de ejecucion.
Func( &clase );
}
;-) simplemente
Mil gracias
ha una ultima cosa
en esta parte
// Error en tiempo de ejecucion
Func( &clase );
es de ejecucion o de compilacion.
ya que me dice
[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
Cita de: nolasco281 en 24 Abril 2014, 10:35 AM
;-) simplemente
Mil gracias
ha una ultima cosa
en esta parte
// Error en tiempo de ejecucion
Func( &clase );
es de ejecucion o de compilacion.
ya que me dice
[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 );
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.
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.
#include <iostream>
class POO
{
int variable;
public:
POO( ) : variable( 1 )
{ }
int Valor( ) { return variable; }
};
void Func( POO& clase )
{
std::cout << clase.Valor( );
}
int main( )
{
POO* clase = 0;
// Error en tiempo de ejecucion
Func( *clase );
clase = new POO( );
// ok
Func( *clase );
delete clase;
// Esto es peligroso con punteros o referencias
// Lo mejor que te puede pasar es un error en tiempo de ejecucion.
Func( *clase );
}
efectiva mente se produce un error.
(http://4.bp.blogspot.com/-ZKypA5ZPmAk/U1jTugqYB8I/AAAAAAAAAr8/sxxqtffsHs8/s1600/Error.png)
Y luego sique su ejecucion.