[C con Clase] Tabla del tipo de mi clase
Steven Davidson
srd4121 en njit.edu
Vie Jul 30 20:07:18 CEST 2010
Hola Javi,
Javi wrote:
> Buenas.
> Estoy intentando hacer una tabla del tipo de mi clase ,pero no se
> como hacerlo. mi clase es la siguiente:
Veo algunas cosas que podemos arreglar en esta definición.
> class lugar{
> private:
> string nombre;
> string info;
> public:
> lugar(string nombre,string info){
> this->nombre=nombre;
> this->info=info;
> }
En primer lugar, aconsejo pasar estos parámetros por referencia, para no
tener que instanciar objetos locales de la clase 'string'. Como no nos
interesa modificar estos parámetros - su contenido - indicamos 'const'.
Esto quedaría así:
lugar( const string &nombre, const string &info )
{
this->nombre = nombre;
this->info = info;
}
Para establecer estos parámetros como valores iniciales a los datos
privados, sugiero usar la lista inicializadora del constructor. Esto es,
lugar( const string &sNombre, const string &sInfo )
: nombre(sNombre), info(sInfo)
{}
Básicamente, estamos haciendo esto:
string nombre = sNombre;
string info = sInfo;
que viene a ser lo mismo que esto:
string nombre( sNombre );
string info( sInfo );
> string getInfo ();
> string getNombre ();
> };
> string Lugar::getInfo()
> {
> return info;
> }
> string Lugar::getNombre(){
> return nombre;
> }
>
Esto puede estar bien como está, pero sí aconsejo indicar que son
funciones miembro constantes; esto es,
string Lugar::getInfo() const
{
return info;
}
string Lugar::getNombre() const
{
return nombre;
}
Así indicamos que estas funciones no tienen intención alguna de
modificar el estado del objeto que las invoca. Dicho de otra manera,
estas funciones prometen no modificar los datos privados del objeto de
esta clase.
También creo que quedaría mejor retornando referencias cosntantes de los
miembros; o sea, así:
const string & Lugar::getInfo() const
{
return info;
}
const string & Lugar::getNombre() const
{
return nombre;
}
Así no tenemos que instanciar nuevos objetos. Ciertamente, no podemos
modificar lo retornado al invocar estas funciones, pero posiblemente eso
no sea un grave problema. Siempre podemos isntanciar un objeto
temporalmente a partir de la referencia retornada por esta función
miembro, si nos interesa. Por ejemplo,
lugar obj( "Pablo", "programador" );
string str = obj.getNombre() + ":" + obj.getInfo();
Aquí no tenemos un problema, porque el operador + está sobrecargado para
aceptar referencias a 'string' constantes. Este operador retornará un
nuevo objeto instanciado.
Por otro lado, si nos interesa hacer esto:
string str = mayusculas( obj.getNombre() );
donde 'mayusculas()' acepta una referencia a 'string' para modificarla,
entonces tendríamos que adaptar el código para que pueda funcionar
correctamente con nuestra nueva versión de 'getNombre()'. Podríamos
hacer esto:
string str = mayusculas( string(obj.getNombre()) );
En este caso, también podríamos haber optado por invertir la lógica:
string str( obj.getNombre() );
mayusculas( str );
> Me podeis ayudar a declarar y acceder a la una tabla del tipo lugar??
Sospecho que con "tabla" te refieres a un array bidimensional. Esto
simplemente es,
lugar tabla[100][200];
El problema es que tal y como has definido tu clase 'lugar', el
compilador te va a lanzar errores. Esto es porque en el momento de
definir este array, se instancian 20.000 (100 x 200) objetos de la clase
'lugar'. Como el constructor de 'lugar' requiere dos parámetros, y no se
los hemos dado, el compilador se quejará porque no encuentra una versión
del constructor sin parámetros.
Esto implica que tenemos dos soluciones principales:
1. Definimos un constructor sin parámetros para 'lugar', o
2. diseñamos otra estructura para representar una tabla, en la cual nos
permite instanciar cada objeto con dos parámetros.
Me inclino a sugerir que implementes la primera solución. Siempre es una
buena práctica definir un constructor sin parámetros. A veces se
necesita tal constructor, aunque no vayamos a usarlo explícitamente. Por
ejemplo,
class lugar
{
...
lugar() {} // constructor sin parámetros
};
Y así, podemos hacer esto:
lugar tabla[100][200];
Automáticamente, al definir 'tabla', se instancian los objetos de
'lugar' usando su constructor sin parámetros.
La otra alternativa es usando otra estructura de datos, como por ejemplo
una lista dinámicamente enlazada, en la cual instanciamos cada objeto
pasando los parámetros específicos a cada uno. Por ejemplo, usando las STL:
vector< list< lugar > > tabla( 100 ); // 100 filas x 200 columnas
list< lugar > fila;
// 200 objetos para la 1ª fila
fila.push_back( lugar("Madrid","Capital") );
fila.push_back( lugar("Ciudad Real","Capital") );
fila.push_back( lugar("Toledo","Capital") );
fila.push_back( lugar("Guadalajara","Capital") );
...
tabla.push_back( fila ); // Copiamos la 1ª fila a 'vector'
// 200 objetos para la 2ª fila
fila.clear(); // vaciamos la lista
fila.push_back( lugar("Washington, DC","Capital") );
fila.push_back( lugar("Trenton","Capital") );
fila.push_back( lugar("Albany","Capital") );
fila.push_back( lugar("Filadelfia","Capital") );
...
tabla.push_back( fila ); // Copiamos la 2ª fila a 'vector'
// Así hasta terminar con 100 listas de 200 elementos de tipo 'lugar'
...
Obviamente, he sido explícito en el ejemplo, pero sospecho que
conseguirás esta información de un fichero o del usuario o incluso generado.
La otra opción que se me acaba de ocurrir es la de crear una tabla de
punteros a objetos de tipo 'lugar'. Esto es,
lugar *tabla[100][200];
Esto significa que deberás instanciar cada objeto apuntado. Lo más
seguro es que adjudicarás memoria dinámicamente para cada putnero. Por
ejemplo,
tabla[0][0] = new lugar("Madrid","Capital");
tabla[0][1] = new lugar("Ciudad Real","Capital");
tabla[0][2] = new lugar("Toledo","Capital");
tabla[0][3] = new lugar("Guadalajara","Capital");
...
tabla[1][0] = new lugar("Washington, DC","Capital");
tabla[1][1] = new lugar("Trenton","Capital");
tabla[1][2] = new lugar("Albany","Capital");
tabla[1][3] = new lugar("Filadelfia","Capital");
...
Claro está, tendrás que eliminar la memoria previamente adjudicada,
cuando ya no necesites esa información. Esto supone otra lista de
operaciones 'delete'.
Espero que esto te oriente.
Steven
Más información sobre la lista de distribución Cconclase