[C con Clase] Ayúda con programa de Pila

Steven Davidson srd4121 en njit.edu
Mie Abr 27 19:13:21 CEST 2011


Hola Fernando,

Antes de continuar, te doy la bienvenida a nuestra lista de correo-e.

On 4/27/2011 11:37 AM, fernando wrote:
> tengo implementada la clase Nodo así:

Veamos el código fuente.

> #ifndef __CLASSNodo
>
> #define __CLASSNodo
>
>
>
> #include<string.h>
>

Este nombre no es estándar. Debería ser:

#include <string>

Si usas un compilador antiguo, es posible que tengas que usar 
<string.h>, pero si no, entonces adhiérete al estándar actual.

>
>
> #include "Vehiculo.h"
>
> #include "Carro.h"
>
> #include "Moto.h"
>
> #include "Camion.h"
>
> #include "Furgoneta.h"
>

Sólo necesitas "Vehiculo.h" y ninguno de los ficheros de cabecera de las 
clases derivadas de 'Vehiculo'.

>
>
> using namespace std;
>
>
>
> class Nodo
>
> {
>
>      public:
>
>          enum Tipo {Car,Mot,Cam,Furgo};
>

Esto no es la forma adecuada de programar orientado a objetos. No 
necesitas para nada este "tipo".

>      private:
>
>          Tipo tipo;
>
>          Vehiculo* vehiculo;
>

Dependiendo de lo que te han enseñado, no necesitas 'tipo'. El mecanismo 
de polimorfismo implementa algo parecido a lo que intentas hacer. 
Simplemente usa un puntero a 'Vehiculo' para usar polimorfismo. 
Obviamente 'Vehiculo' debe estar definida como una clase que contenga 
funciones virtuales.

Además, veo que defines funciones miembro en 'Nodo' que no tienen nada 
que ver con el concepto de un "nodo". Por ejemplo, 'asignarValores()' y 
'obtenerValores()'. Como no deberías usar este sistema de "tipos", las 
otras funciones miembro que los manipulan tampoco las necesitas: el 
constructor 'Nodo()' que requiere parámetros, 'obtenerTipo()', y 
'obtenerTipoEnum()'.

No necesitas este segundo constructor, pero si otro que requiera un 
puntero a 'Vehiculo'. Esto es,

Nodo( Vehiculo *ptr );

Al final, tu clase queda así:

class Nodo
{
private:
   Vehiculo* vehiculo;
   Nodo* punteroSiguiente;

public:
   Nodo();  // No creo que sea necesario
   Nodo( Vehiculo *ptr );  // 'ptr' no debería ser nulo

   void asignarSiguiente( Nodo* nuevoNodo );
   Nodo* obtenerSiguiente();

   const Vehiculo *obtener() const;  // Lectura
   Vehiculo *obtener();              // Escritura
};

Si quieres obtener los valores del vehículo, tanto para modificarlos 
como para "leerlos", entonces usar SUS funciones miembro para lograr 
estos objetivos. Sin embargo, no es una buena idea dejar que 'Nodo' 
realice estas operaciones, ya que no es su responsabilidad de conocer 
los detalles de la clase 'Vehiculo'. Aquí, la clase 'Nodo' sólo se 
preocupa de contener (guardar) el puntero a 'Vehiculo'; ni más ni menos. 
Por esta razón, se suele hablar de "clases contenedoras" o simplemente, 
"contendor".

No he colocado un destructor para 'Nodo', porque esto depende de ti. Una 
posibilidad es mantener el destructor, el cual liberará la memoria 
adjudicada previamente para el objeto polimórfico apuntado por 'ptr'. 
Esto significa que decides que 'Nodo' se haga cargo de la liberación de 
la memoria de 'vehiculo'. Por otra parte, puedes decidir que 'Nodo' no 
se hará cargo de tal liberación, por lo que corre de cuenta de otra 
parte del programa; seguramente, la clase que implementa la lista 
dinámicamente enlazada es quién liberará la memoria.

Para más información acerca del polimorfismo, consulta el capítulo 37 de 
nuestro curso de C++ yendo a: 
http://c.conclase.net/curso/index.php?cap=037#039_polimorfismo


Espero que todo esto te ayude.

Steven





Más información sobre la lista de distribución Cconclase