Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: nolasco281 en 4 Febrero 2014, 21:57 pm



Título: El for no me hace su funcion? (Solucionado)
Publicado por: nolasco281 en 4 Febrero 2014, 21:57 pm
Hola.

Espero que me pueda ayudar con mi duda estoy tratando de hacer métodos de administración, pero al momento de mostrar datos en pantalla no sé qué estoy haciendo mal.

No es un error de sintaxis creo que es mas de lógica pero no entiendo que parte es la que trabaja mal.

El problema que detecto es en el archivo de implementación de Camion.cpp en la función Camion::flistaDeCamiones() en el for cuando intento acceder a la a listaDeCamiones->imprimir(); el primer registro si lo introduce bien pero cuando le agrego otro, el programa se cierra y parece, que borrara el primer registro.

Y eso no me deja seguir con los demás métodos.

he sacado la funcion imprimir fuera del for por solo me registra una ves los datos, y no una secuencia, si lo pongo antes de empezar el for me hace la secuencia pero me repite los ultimos datos las veces que haya registrado un camion.

Lamento preguntar tanto.

//Camion.cpp
Código
  1. #include "Camion.h"
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8. Camion::Camion (int idCam, int cilindrajeCam, int puertasCam, int anioCam,
  9.                double precioCam, string marcaCam, string modeloCam,
  10.                string colorCam)
  11.                {
  12.                   idCamion = idCam;
  13.                   cilindrajeCamion = cilindrajeCam;
  14.                   nPuertasCamion = puertasCam;
  15.                   anioCamion = anioCam;
  16.                   precioCamion = precioCam;
  17.                   marcaCamion = marcaCam;
  18.                   modeloCamion = modeloCam;
  19.                   colorCamion = colorCam;
  20.  
  21.                   Maximo =100;
  22.                   cantidadDeCamiones =0;
  23.                }
  24. //Funciones set
  25. void Camion::setIdCamion(int idCam)
  26. {
  27.     idCamion = idCam;
  28. }
  29.  
  30. void Camion::setCilindrajeCamion(int cilindrajeCam)
  31. {
  32.     cilindrajeCamion = cilindrajeCam;
  33. }
  34.  
  35. void Camion::setNPuertasCamion(int puertasCam)
  36. {
  37.     nPuertasCamion = puertasCam;
  38. }
  39.  
  40. void Camion::setanioCamion(int anioCam)
  41. {
  42.     anioCamion = anioCam;
  43. }
  44.  
  45. void Camion::setPrecioCamion(double precioCam)
  46. {
  47.     precioCamion = precioCam;
  48. }
  49.  
  50. void Camion::setMarcaCamion(string marcaCam)
  51. {
  52.     marcaCamion = marcaCam;
  53. }
  54.  
  55. void Camion::setModeloCamion(string modeloCam)
  56. {
  57.     modeloCamion = modeloCam;
  58. }
  59.  
  60. void Camion::setColorCamion(string colorCam)
  61. {
  62.     colorCamion = colorCam;
  63. }
  64.  
  65. //Funciones get
  66. int Camion::getIdCamion() const
  67. {
  68.    return idCamion;
  69. }
  70.  
  71. int Camion::getCilindrajeCamion() const
  72. {
  73.    return cilindrajeCamion;
  74. }
  75.  
  76. int Camion::getnPuertasCamion() const
  77. {
  78.    return nPuertasCamion;
  79. }
  80.  
  81. int Camion::getanioCamion()const
  82. {
  83.    return anioCamion;
  84. }
  85.  
  86. double Camion::getPrecioCamion() const
  87. {
  88.       return precioCamion;
  89. }
  90.  
  91. string Camion::getMarcaCamion() const
  92. {
  93.       return marcaCamion;
  94. }
  95.  
  96. string Camion::getModeloCamion() const
  97. {
  98.       return modeloCamion;
  99. }
  100.  
  101. string Camion::getColorCamion() const
  102. {
  103.       return colorCamion;
  104. }
  105.  
  106. //Ingresa un nuevo camion
  107.  
  108. void Camion::ingresarCamion()
  109. {
  110.   listaDeCamiones = new Camion*[Maximo];// arreglo de 100
  111.  
  112.   if (cantidadDeCamiones < Maximo)
  113.   {
  114.     system("cls");
  115.     cout << "Ingrese los datos del camion\n";
  116.     cout << "Ingrese el ID del camion: ";
  117.     cin  >> idCamion;
  118.  
  119.     cout << "Ingrese la Marca del Camion: ";
  120.     cin  >> marcaCamion;
  121.  
  122.     cout << "Ingrese el Modelo del camion: ";
  123.     cin  >> modeloCamion;
  124.  
  125.     cout << "Ingrese el año del Camion: ";
  126.     cin  >> anioCamion;
  127.  
  128.     cout << "Ingrese el cilindraje del camion: ";
  129.     cin  >> cilindrajeCamion;
  130.  
  131.     cout << "Ingrese el numero de puertas: ";
  132.     cin  >>  nPuertasCamion;
  133.  
  134.     cout << "Ingrese el color del camion: ";
  135.     cin  >> colorCamion;
  136.  
  137.     cout << "Ingrese el presio del camion: ";
  138.     cin  >> precioCamion;
  139.  
  140.     listaDeCamiones[cantidadDeCamiones] =
  141.     new Camion(idCamion, cilindrajeCamion,
  142.         nPuertasCamion, anioCamion,
  143.         precioCamion, marcaCamion,
  144.         modeloCamion,colorCamion);
  145.  
  146.     cantidadDeCamiones++;
  147.  
  148.     cout << endl <<"Los datos del camion fueron ingresados correctamente\n";
  149.   }
  150.   else
  151.   {
  152.       system("cls");
  153.       cout << "Ya no hay espacio disponible para mas camiones\n";
  154.   }
  155. }
  156.  
  157. //Muestra los datos del camion
  158. void Camion::flistaDeCamiones()
  159. {
  160.     if (cantidadDeCamiones==0)
  161.     {
  162.       system("cls");
  163.       cout<<"No se a registrado ninguna Camion todavía"<<endl;
  164.     }
  165.       else
  166.       {
  167.           cout<<"..:::Lista de Camiones:::.."<<endl<<endl;
  168.           cout << setw(10)<<"Id Camion"<<setw(15)<<"Modelo"<<setw(15)<<"marca"<<endl;
  169.           cout<<"================================================="<<endl;
  170.  
  171.           //Imprimmir todos los camiones almacenadas en el arreglo
  172.           for (int i=0; i<cantidadDeCamiones; i++)
  173.           {
  174.             listaDeCamiones[i]->imprimir(); //PROBLEMA Y NO LO IDENTIFICO
  175.           }
  176.           cout<<endl<<"*******Fin de la lista **********"<<endl<<endl;
  177.       }
  178. }
  179. //Busca ese camion
  180. int Camion::buscarCamion(int codigo)
  181. {
  182.    for (int i=0; i < cantidadDeCamiones; i++)
  183.    {
  184.        if(listaDeCamiones[i]->getIdCamion() == codigo)
  185.        {
  186.          return i;
  187.        }
  188.    }
  189.    return -1;
  190. }
  191.  
  192. //Modifica ese Camion.
  193. void Camion::modificarCamion()
  194. {
  195.     if (cantidadDeCamiones == 0)
  196.     {
  197.       system("cls");
  198.       cout << "No se ha registrado ningun camion tadavia\n";
  199.     }
  200.     else
  201.     {
  202.         cout << "Modificar Camion\n\n";
  203.         int codigoCamion;
  204.         cout << "Ingrese el codigo del camion: ";
  205.         cin >> codigoCamion;
  206.  
  207.         int ubicacion = buscarCamion(codigoCamion);
  208.         if (ubicacion == -1)
  209.         {
  210.           cout << "Lo sentimos ese codigo del camion no existe\n";
  211.         }
  212.         else
  213.         {
  214.             cout << "El codigo se encontro\n\n";
  215.             cout << setw(10)<<"Id"<<setw(15)<<"Modelo"<<setw(15)<<"marca"<<endl;
  216.             cout<<"================================================="<<endl;
  217.  
  218.             listaDeCamiones[ubicacion]->imprimir();
  219.             cout << "\n\n";
  220.             cout  << "Ingrese los nuevos datos del Camion\n\n";
  221.  
  222.             cout <<  "Marca";
  223.             cin  >> marcaCamion;
  224.  
  225.             cout << "Modelo del camion: ";
  226.             cin  >> modeloCamion;
  227.  
  228.             cout << "Año del Camion: ";
  229.             cin  >> anioCamion;
  230.  
  231.             cout << "Cilindraje del camion: ";
  232.             cin  >> cilindrajeCamion;
  233.  
  234.             cout << "numero de puertas: ";
  235.             cin  >>  nPuertasCamion;
  236.  
  237.             cout << "Color del camion: ";
  238.             cin  >> colorCamion;
  239.  
  240.             cout << "Presio del camion: ";
  241.             cin  >> precioCamion;
  242.  
  243.             listaDeCamiones[ubicacion]->setMarcaCamion(marcaCamion);
  244.             listaDeCamiones[ubicacion]->setModeloCamion(modeloCamion);
  245.             listaDeCamiones[ubicacion]->setanioCamion(anioCamion);
  246.             listaDeCamiones[ubicacion]->setCilindrajeCamion(cilindrajeCamion);
  247.             listaDeCamiones[ubicacion]->setNPuertasCamion(nPuertasCamion);
  248.             listaDeCamiones[ubicacion]->setColorCamion(colorCamion);
  249.             listaDeCamiones[ubicacion]->setPrecioCamion(precioCamion);
  250.  
  251.             cout << "El camion fue modificado Exitosamente.\n";
  252.         }
  253.     }
  254. }
  255.  
  256. void Camion::eliminarCamion()
  257. {
  258.     if (cantidadDeCamiones == 0)
  259.     {
  260.       system("cls");
  261.       cout << "No se ha registrado ningun camion tadavia\n";
  262.     }
  263.     else
  264.     {
  265.         cout << "Eliminar Camion\n\n";
  266.         int codigoCamion;
  267.         cout << "Ingrese el codigo a eliminar: ";
  268.         cin >> codigoCamion;
  269.  
  270.         int ubicacion = buscarCamion(codigoCamion);
  271.         if (ubicacion == -1)
  272.         {
  273.           cout << "Lo sentimos ese codigo del camion no existe\n";
  274.         }
  275.         else
  276.         {
  277.             cout << "El codigo se encontro\n\n";
  278.             cout << setw(10)<<"Id"<<setw(15)<<"Modelo"<<setw(15)<<"marca"<<endl;
  279.             cout<<"================================================="<<endl;
  280.  
  281.             listaDeCamiones[ubicacion]->imprimir();
  282.             cout << "\n\n";
  283.  
  284.             cout << "Presione enter para eliminar ese camion\n\n";
  285.             system("pause");
  286.  
  287.             //Pasa a eliminar usando una copia del arreglo
  288.             Camion**temporalListaDeCamiones = new Camion*[Maximo];
  289.             int temporalCantidadDeCamiones = 0;
  290.  
  291.             //Se copia el arreglo en otro arreglo exepto el que se quiere eliminar
  292.             for(int i =0; i < cantidadDeCamiones; i++)
  293.             {
  294.               if(i!=ubicacion)
  295.               {
  296.                 temporalListaDeCamiones[temporalCantidadDeCamiones] = new Camion(listaDeCamiones[i]->getIdCamion(),
  297.                                                                                  listaDeCamiones[i]->getCilindrajeCamion(),
  298.                                                                                  listaDeCamiones[i]->getnPuertasCamion(),
  299.                                                                                  listaDeCamiones[i]->getanioCamion(),
  300.                                                                                  listaDeCamiones[i]->getPrecioCamion(),
  301.                                                                                  listaDeCamiones[i]->getMarcaCamion(),
  302.                                                                                  listaDeCamiones[i]->getModeloCamion(),
  303.                                                                                  listaDeCamiones[i]->getColorCamion());
  304.                 temporalCantidadDeCamiones++;
  305.               }//Fin if
  306.             }//Fin for
  307.  
  308.             //Limpio la memoria usada por el arreglo principal de camiones
  309.             for(int i=0; i<cantidadDeCamiones; i++)
  310.             {
  311.               listaDeCamiones[i]->~Camion();
  312.             }
  313.  
  314.             //copia el arreglo temporal al principio
  315.             cantidadDeCamiones = 0;
  316.             for(int i =0; i<temporalCantidadDeCamiones; i++)
  317.             {
  318.                listaDeCamiones[cantidadDeCamiones] = new Camion(temporalListaDeCamiones[i]->getIdCamion(),
  319.                                                                 temporalListaDeCamiones[i]->getCilindrajeCamion(),
  320.                                                                 temporalListaDeCamiones[i]->getnPuertasCamion(),
  321.                                                                 temporalListaDeCamiones[i]->getanioCamion(),
  322.                                                                 temporalListaDeCamiones[i]->getPrecioCamion(),
  323.                                                                 temporalListaDeCamiones[i]->getMarcaCamion(),
  324.                                                                 temporalListaDeCamiones[i]->getModeloCamion(),
  325.                                                                 temporalListaDeCamiones[i]->getColorCamion());
  326.                cantidadDeCamiones++;
  327.             }//Fin for
  328.             cout << "El camion fue eliminado exitosamente\n\n";
  329.         }//fin else
  330.     }
  331.  
  332. }
  333.  
  334. //Imprime los datos del Camion
  335. void Camion::imprimir()
  336. {
  337.     cout<<setw(10)<<idCamion<<setw(15)<<modeloCamion<<setw(15)<<marcaCamion<<endl;
  338. }

//.h
Código
  1. #ifndef CAMION_H
  2. #define CAMION_H
  3. #include <iostream>
  4. using namespace std;
  5. // Variables globales
  6. class Camion
  7. {
  8.      private:
  9.      int idCamion;
  10.      int cilindrajeCamion;
  11.      int nPuertasCamion;
  12.      int anioCamion;
  13.      double precioCamion;
  14.      string marcaCamion, modeloCamion, colorCamion;
  15.  
  16.      public:
  17.      Camion(int =0, int=0, int=0, int=0, double = 0.0, string = "", string = "", string = "");
  18.  
  19.      void setIdCamion(int);
  20.      void setCilindrajeCamion(int);
  21.      void setNPuertasCamion(int);
  22.      void setanioCamion(int);
  23.      void setPrecioCamion(double);
  24.      void setMarcaCamion(string);
  25.      void setModeloCamion(string);
  26.      void setColorCamion(string);
  27.  
  28.      int getIdCamion() const;
  29.      int getCilindrajeCamion() const;
  30.      int getnPuertasCamion() const;
  31.      int getanioCamion() const;
  32.      string getMarcaCamion() const;
  33.      string getModeloCamion() const;
  34.      string getColorCamion() const;
  35.      double getPrecioCamion() const;
  36.  
  37.      //Otros Metodos
  38.      void ingresarCamion();
  39.      void flistaDeCamiones();
  40.      void imprimir();
  41.      int buscarCamion(int);
  42.      void modificarCamion();
  43.      void eliminarCamion();
  44.  
  45.      private:
  46.      Camion**listaDeCamiones;
  47.      int Maximo;
  48.      int cantidadDeCamiones;
  49.  
  50. };
  51. #endif

//principal
Código
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include "Camion.h"
  4.  
  5. using namespace std;
  6.  
  7. void menuCamiones();
  8.  
  9. int main(int argc, char *argv[])
  10. {    
  11.     menuCamiones();
  12.    system("PAUSE");
  13.    return EXIT_SUCCESS;
  14. }
  15.  
  16. void menuCamiones()
  17. {
  18.     Camion camionOb;
  19.     int opcion;
  20.     do
  21.     {
  22.         system("cls");
  23.         cout << "Menu\n"
  24.              << "1.Desea ingresar un nuevo camion a la empresa\n"
  25.              << "2. mostrar lista de Camiones\n";
  26.         cout << "Elija una opcion: ";
  27.         cin >> opcion;
  28.  
  29.         switch(opcion)
  30.         {
  31.         case 1:
  32.              system("cls");
  33.              camionOb.ingresarCamion();
  34.              system("pause");
  35.              break;
  36.  
  37.          case 2:
  38.               system("cls");
  39.               camionOb.flistaDeCamiones();
  40.               system("pause");
  41.          break;        
  42.  
  43.          case 3:
  44.          break;
  45.  
  46.          default:
  47.                  cout << "Esa opcion no existe.\n\n";
  48.                  break;
  49.         }
  50.  
  51.  
  52.     }while(opcion != 3);
  53. }

Gracias.


Título: Re: El for no me hace su funcion?
Publicado por: Yoel Alejandro en 5 Febrero 2014, 00:02 am
Hola nolasco, acabo de revisar tu código. En rasgos generales, pero tienes como un pequeño problema de organización. Fíjate que estás guardando la cantidad de camiones como un miembro de cada objeto (o "instancia") de la clase Camion. Eso es absurdo. Imagínate que creas un primer objeto Camion, entonces su campo cantidadDeCamiones tiene el valor de 1, porque hasta el momento has creado un solito objeto de dicha clase.

Ahora creas otro camión. El primero tiene el campo cantidadDeCamiones = 1, el segundo tiene cantidadDeCamiones = 2, porque (a menos que yo haya leído mal el código) tú no actualizas el campo cantidadDeCamiones en cada uno de los objetos anteriormente creados de la clase Camion (¿verdad?). Y creo que precisamente por eso es que te imprime uno solo, porque la primera instancia creada tiene el valor cantidad de camiones en "1".

En todo caso, hacer esto de esa manera tampoco sería lo ideal. Yo te recomendaría definir una clase aparte listaCamiones con dos únicos campos: Uno un arreglo de camiones y otro un entero indicando la cantidad de camiones creados hasta el momento:

Código:
class listaCamiones {
public:
    Camion Camiones[ MAXIMO ];
    int N_Camiones;
}

La constante MAXIMO (que tú quieres sea 100) yo te recomiendo la definas como una macro de cabecera:

Código:
#define MAXIMO 100

ya que es un valor que se supone debe permanecer constante durante todo el programa (si la pones como variable int, ¿te imaginas qué pasaría si por error cambias su valor durante el programa?)

Los métodos ingresarCamion(), flistaDeCamiones(), imprimir(), buscarCamion(int), modificarCamion(), eliminarCamion() serían de la clase listaCamiones, y no de la clase individual Camion (¿vas captando la idea?). Al añadir un nuevo camión puedes hacer algo como esto:

Código:
void listaCamiones :: ingresarCamion( ) {
   
    /* aquí pides los datos para el nuevo camión */

    /* creas una instancia de Camion */
    Camion new_Camion = new Camion( idCamion, cilindrajeCamion,
        nPuertasCamion, anioCamion,
        precioCamion, marcaCamion,
        modeloCamion,colorCamion);

    /* y la añades al arreglo, actualizando el contador */
    Camiones[ N_Camiones++ ] = new_Camion;
}

Ahora debes definir la función de imprimir lista como un método de la clase listaCamiones, y ya debería imprimir todos los camiones.
En fin, sólo hace falta una pequeña reingeniería del software (mover unas cosas de aquí para allá) y debería estar funcionando bien.

Saludos, y cualquier cosa comenta, .... :) Yoel.


Título: Re: El for no me hace su funcion?
Publicado por: nolasco281 en 5 Febrero 2014, 02:31 am
Hola yoel_alejandro gracias por contestar ahora lo leeo


Título: Re: El for no me hace su funcion?
Publicado por: nolasco281 en 5 Febrero 2014, 03:59 am
Hola ya cree la clase y le paso los datos pero ahora me dice.
lamento preguntar tanto. pero me quiero arrancar la cabeza.

Hola pense que era por que no habia includio la libreria de string o el usign namespace std; pero no.

y se que hace referencia al constructor de la clase camion pero veo que le mando los parametros o argumentos correctos.

Ya note donde está el problema es que no estoy apuntando a nada. Según leí  Cuando se usa el operador new se tiene que usar apuntadores a fuerza. Y ese es el problema espero resolverlo pronto.

(http://1.bp.blogspot.com/-ruTXNqfWrV0/UvGp9MKSWCI/AAAAAAAAAfM/uGZT2wzLyWY/s1600/sdf.png)

Código
  1. #ifndef LISTACAMIONES_H
  2. #define LISTACAMIONES_H
  3. #include "Camion.h"
  4. #define Maximo 100
  5.  
  6. class listaCamiones
  7. {
  8.      Camion camiones[Maximo];
  9.      int nCamiones;
  10.  
  11.      //Ingresa un nuevo camion
  12. void listaCamiones::ingresarCamion()
  13. {
  14.     int idCamion, anioCamion, cilindrajeCamion, nPuertasCamion;
  15.     double precioCamion;
  16.     string colorCamion, marcaCamion, modeloCamion;
  17.    //listaDeCamiones = new Camion*[Maximo];// arreglo de 100
  18.  
  19.   if (nCamiones < Maximo)
  20.   {
  21.     system("cls");
  22.     cout << "Ingrese los datos del camion\n";
  23.     cout << "Ingrese el ID del camion: ";
  24.     cin  >> idCamion;
  25.  
  26.     cout << "Ingrese la Marca del Camion: ";
  27.     cin  >> marcaCamion;
  28.  
  29.     cout << "Ingrese el Modelo del camion: ";
  30.     cin  >> modeloCamion;
  31.  
  32.     cout << "Ingrese el año del Camion: ";
  33.     cin  >> anioCamion;
  34.  
  35.     cout << "Ingrese el cilindraje del camion: ";
  36.     cin  >> cilindrajeCamion;
  37.  
  38.     cout << "Ingrese el numero de puertas: ";
  39.     cin  >>  nPuertasCamion;
  40.  
  41.     cout << "Ingrese el color del camion: ";
  42.     cin  >> colorCamion;
  43.  
  44.     cout << "Ingrese el presio del camion: ";
  45.     cin  >> precioCamion;
  46.  
  47.     Camion nuevoCamion = new Camion(idCamion, cilindrajeCamion, nPuertasCamion,
  48.                                     anioCamion, precioCamion, marcaCamion, modeloCamion,
  49.                                     colorCamion);
  50.  
  51.     camiones [nCamiones++] = nuevoCamion;
  52.  
  53.     cout << endl <<"Los datos del camion fueron ingresados correctamente\n";
  54.   }
  55.   else
  56.   {
  57.       system("cls");
  58.       cout << "Ya no hay espacio disponible para mas camiones\n";
  59.   }
  60. }
  61.  
  62. };
  63.  
  64. #endif


Título: Re: El for no me hace su funcion?
Publicado por: nolasco281 en 5 Febrero 2014, 07:44 am
Código
  1. Camion new_Camion = new Camion( idCamion, cilindrajeCamion,
  2.        nPuertasCamion, anioCamion,
  3.        precioCamion, marcaCamion,
  4.        modeloCamion,colorCamion);
  5.  
  6.    /* y la añades al arreglo, actualizando el contador */
  7.    Camiones[ N_Camiones++ ] = new_Camion;

no se, si se le olvido a yoel_alejandro asignar el apuntador hice esto.
pero el arreglo a la hora ingresar un registro del camion entra de un solo al else y me dice que ya no hay espacio para mas camiones  :-(

Código
  1. Camion *nuevoCamion = new Camion(idCam, cilindrajeCam,  
  2.                             nPuertasCam,  anioCam,  
  3.                             precioCam, marcaCam,
  4.                             modeloCam, colorCam);
  5.  
  6. Camiones[nCamiones++] = *nuevoCamion;


Título: Re: El for no me hace su funcion?
Publicado por: eferion en 5 Febrero 2014, 08:53 am
Código
  1. Camion(int =0, int=0, int=0, int=0, double = 0.0, string = "", string = "", string = "");

Esta declaración será broma, no???

No te recomiendo crear, de buenas a primeras, funciones que usen más de 4 argumentos porque es poco usable... si cometes el error de invertir dos argumentos te vas a dar de cabezazos hasta que des con el problema.

Además es altamente recomendable que en la declaración de las funciones aparezcan los nombres de los argumentos... normalmente cuando estés programando mirarás el archivo de cabecera para recordar el uso de las funciones, ya que suelen ser más sencillos de consultar... si tienen 20 argumentos y encima no están etiquetados te quedas sin esta opción.

Por otro lado, otra sugerencia, deberías eliminar el using namespace std de los archivos de cabecera. Usar espacios de nombres en los archivos de cabecera es una mala práctica porque obliga a arrastrar ese uso a todos los archivos que incluyan esa cabecera... y en algunos casos puede ser contraproducente... por ejemplo si dos funciones o clases se llaman igual y están en espacios de nombres diferentes.

Código
  1. namespace N1
  2. {
  3.  void func( );
  4. }
  5.  
  6. namespace N2
  7. {
  8.  void func( );
  9. }
  10.  
  11. using namespace N1;
  12. using namespace N2;
  13.  
  14. void main( )
  15. {
  16.  // a que func estamos llamando??
  17.  func( );
  18. }

Más cosillas, si estás usando C++... por qué no usas los contenedores para almacenar la lista de camiones?? Son más potentes, versátiles y seguros que los arreglos.

* Potentes porque ofrecen una interfaz... los arreglos no.

* Versátiles porque se adaptan perfectamente a las necesidades de cada programa, solo hay que elegir correctamente el contenedor a utilizar.

* Seguros porque previenen desbordamientos y otros fallos típicos del uso de memoria dinámica.

Y además son muy sencillos de usar:

Código
  1. std::vector< Camion* > Camiones;
  2. Camiones.push_back( new_camion );
  3.  
  4. Camion* camion = Camiones[ 0 ];
  5.  

no se, si se le olvido a yoel_alejandro asignar el apuntador hice esto.
pero el arreglo a la hora ingresar un registro del camion entra de un solo al else y me dice que ya no hay espacio para mas camiones  :-(

Código
  1. Camion *nuevoCamion = new Camion(idCam, cilindrajeCam,  
  2.                             nPuertasCam,  anioCam,  
  3.                             precioCam, marcaCam,
  4.                             modeloCam, colorCam);
  5.  
  6. Camiones[nCamiones++] = *nuevoCamion;

Si "Camiones" es un arreglo de punteros... "*nuevoCamion" debería ser "nuevoCamion", ya que con el asterisco pasas a usar una variable estática, no un puntero.

Además no has inicializado la variable nCamiones... por lo que ésta pasa a tener un valor aleatorio y, tirando un poco de estadística... si un int ocupa 32 bits y lo llenamos con basura... ¿que posibilidades hay de que el número resultante esté entre cero y 100?? hago constar que con 32 bits el rango de valores va de –2.147.483.648 a 2.147.483.647.

Sin embargo, sacando a relucir el tema del contenedor, el código podría quedar tal que

Código
  1. std::vector< Camion* > camiones;
  2.  
  3. // ...
  4.  
  5. if ( camiones.size( ) < Maximo )
  6. {
  7.  // ...
  8.  
  9.  camiones.push_back( new_camion );
  10. }
  11. else
  12. {
  13.  // ...
  14. }


Título: Re: El for no me hace su funcion?
Publicado por: nolasco281 en 5 Febrero 2014, 09:19 am
Gracias primero que nada

Además es altamente recomendable que en la declaración de las funciones aparezcan los nombres de los argumentos.

tipo nomFuncion(int); //Yo.
tipo nomFuncion(int argumento) //Si no me equivoco esto es lo que me decís pueda que se la costumbre y por eso no lo hago. Pero lo adoptare. Gracias por eso también.

Además es altamente recomendable que en la declaración de las funciones aparezcan los nombres de los argumentos... normalmente cuando estés programando mirarás el archivo de cabecera para recordar el uso de las funciones, ya que suelen ser más sencillos de consultar... si tienen 20 argumentos y encima no están etiquetados te quedas sin esta opción.

Gracias por este consejo siempre etiqueto los métodos lo hago al final pero creo que tienes razón es mejor hacerlo desde un principio.

Por otro lado, otra sugerencia, deberías eliminar el using namespace std de los archivos de cabecera

Totalmente de acuerdo solo que a veces no se cual el problema y me pongo tonto.

Ahorita pruebo he intento todo lo que me has comentado.

Se agradece mucho a todos los que comentan y reitero que se toman su tiempo para ayudarme y además te aconsejan en la buena práctica.

Probando y comento como me va si lo logro.

PD:Me regresaste a la vida loco estaba por, darme, por vencido.


Título: Re: El for no me hace su funcion?
Publicado por: nolasco281 en 5 Febrero 2014, 11:06 am
Hola Muchas gracias a todos, me da hasta un poco de pena molestarlos.
Y antes que nada entiendo si ya no quieren contestar.
Pero como pueden ver no soy muy bueno en C++ y quiero aprenderlo.

Creeo que esta es la parte fea de C++ ;D

Tengo una duda no se si es por que no he dormido

En Camion.cpp tengo el maximo ya lo quite ya que lo defini en la clase listasCamiones.cpp.

Código
  1. Maximo =100;
  2. cantidadDeCamiones =0;

Y en Camion.h eso está bien como lo he modificado tanto que así lo tenía cuando funcionaba pero no de la forma correcta pero ahora que estoy hice clase listaCamiones no sé si sean necesarias.

Código
  1. private:
  2.     Camion**listaDeCamiones;
  3.     //int Maximo;
  4.     int cantidadDeCamiones;

Si se fijan estoy probando tanto vectores me señalo eferion y con arreglos por que se, de que de las dos formas es impórtate hacerlo.

Y este es el error con arreglo de punteros. Que es el que mencionaba de la forma de yoel_alejandro.

(http://2.bp.blogspot.com/-vVsPB85wCIk/UvIOY_Ewa7I/AAAAAAAAAfw/HYn6qs2XbNo/s1600/Arreglos1.png)

Y este es la forma en que me señala eferion.
(http://3.bp.blogspot.com/-oGvU850SAoA/UvIKZu1DErI/AAAAAAAAAfo/a3VOYoVFbgU/s1600/vector.png)



Título: Re: El for no me hace su funcion?
Publicado por: eferion en 5 Febrero 2014, 11:30 am
En Camion.cpp tengo el maximo ya lo quite ya que lo defini en la clase listasCamiones.cpp.

Código
  1. Maximo =100;
  2. cantidadDeCamiones =0;

Y en Camion.h eso está bien como lo he modificado tanto que así lo tenía cuando funcionaba pero no de la forma correcta pero ahora que estoy hice clase listaCamiones no sé si sean necesarias.

Código
  1. private:
  2.     Camion**listaDeCamiones;
  3.     //int Maximo;
  4.     int cantidadDeCamiones;

Prueba a poner la declaración completa de las clases... con lo que has puesto no me hago una idea de cómo ha quedado.


Y este es el error con arreglo de punteros. Que es el que mencionaba de la forma de yoel_alejandro.

...

Y este es la forma en que me señala eferion.

...


Código
  1. Camion nuevoCamion = new Camion( ... );

Ese código está mal. new sirve para crear objetos dinámicos; y los objetos dinámicos tienen que gestionarse usando punteros:

Código
  1. Camion *nuevoCamion = new Camion( ... );

Además, estás redefiniendo la misma variable varias veces

Código
  1. Camion nuevoCamion = new Camion( ... );
  2. Camion nuevoCamion = new Camion( ... );
  3. Camion nuevoCamion = new Camion( ... );

Cada una de esas variables tiene que tener un nombre diferente, al menos si están en el mismo ámbito, lo que sucede en tu caso:

Código
  1. Camion *nuevoCamion1 = new Camion( ... );
  2. Camion *nuevoCamion2 = new Camion( ... );
  3. Camion *nuevoCamion3 = new Camion( ... );

Y tienes que aprender a leer e interpretar los mensajes de error... el último te está diciendo que la varible "nuevoCamion" no existe... si te fijas, en la línea anterior a la instancia de la clase la has llamado "cammion", no "nuevoCamion".

Nota final... ten siempre presente que en tu código ha de haber un delete por cada new que escribas... si no vas a acabar con lagunas de memoria... la memoria reservada por un new no se libera por sí misma.


Título: Re: El for no me hace su funcion?
Publicado por: nolasco281 en 5 Febrero 2014, 11:52 am
El de vectores ya esta, si funciono y me confundi en esta parte por eso no sabia donde declarar esa varible Gracias.

std::vector< Camion* > Camiones;
Camiones.push_back( new_camion );
 
Camion* camion = Camiones[ 0 ]; //1.esta parte

   std::vector< Camion* > camiones;
    
    // ...
    
    if ( camiones.size( ) < Maximo )
    {
     // ...
    
     camiones.push_back( new_camion ); //2.estaparte
    }
    else
    {
     // ...
    }

//Codigo arreglo de punteros
//Camiones.h
Código
  1. #ifndef CAMION_H
  2. #define CAMION_H
  3. #include <iostream>
  4. using namespace std;
  5. // Variables globales si la hay
  6.  
  7. class Camion
  8. {
  9.      //Variables Privadas
  10.      private:
  11.      int idCamion;
  12.      int cilindrajeCamion;
  13.      int nPuertasCamion;
  14.      int anioCamion;
  15.      double precioCamion;
  16.      string marcaCamion, modeloCamion, colorCamion;
  17.  
  18.  
  19.      public:
  20.  
  21.      //Constructores.
  22.      Camion(int =0, int=0, int=0, int=0);
  23.      Camion(double =0.0);
  24.      Camion(string = "", string = "", string = "");
  25.  
  26.      //Funciones o metodos publicos
  27.      void setIdCamion(int);         //Devuelve el Id del Camion.
  28.      void setCilindrajeCamion(int); //Devuelve el cilindrage del camion
  29.      void setNPuertasCamion(int);   //Devuelve el numero de puertas del camion
  30.      void setanioCamion(int);       //Devuelve el año del camion
  31.      void setPrecioCamion(double);  //Devuelve el precio del camion
  32.      void setMarcaCamion(string);   //Devuelve la marca del camion
  33.      void setModeloCamion(string);  //Devuelve el modelo del camion
  34.      void setColorCamion(string);   //Devuelve el color del camion
  35.  
  36.      int getIdCamion() const;         //Obtiene Id del Camion.
  37.      int getCilindrajeCamion() const; //Obtiene el cilindrage del camion
  38.      int getnPuertasCamion() const;   //Obtiene numero de puertas del camion
  39.      int getanioCamion() const;       //Obtiene el año del camion
  40.      double getPrecioCamion() const;  //Obtiene el precio del camion
  41.      string getMarcaCamion() const;   //Obtiene la marca del camion
  42.      string getModeloCamion() const;  //Obtiene el modelo del camion
  43.      string getColorCamion() const;   //Obtiene el color del camion
  44.  
  45.  
  46.      //Otros Metodos
  47.      void ingresarCamion();
  48.      void flistaDeCamiones();
  49.      void imprimir();
  50.      int buscarCamion(int);
  51.      void modificarCamion();
  52.      void eliminarCamion();
  53.  
  54.      private:
  55.      Camion**listaDeCamiones;
  56.      int cantidadDeCamiones;
  57.  
  58. };
  59. #endif

//Camion.cpp
Código
  1. #include "Camion.h"
  2. #include <iostream>
  3. #include <iomanip>
  4. #include <string>
  5.  
  6. //Constructores valores enteros
  7. Camion::Camion (int idCam, int cilindrajeCam, int puertasCam, int anioCam)
  8. {
  9.  idCamion = idCam;
  10.  cilindrajeCamion = cilindrajeCam;
  11.  nPuertasCamion = puertasCam;
  12.  anioCamion = anioCam;
  13.  cantidadDeCamiones =0;
  14. }
  15.  
  16. //Constructores valores double
  17. Camion::Camion(double precioCam)
  18. {
  19.  precioCamion = precioCam;
  20. }
  21.  
  22. //Constructores valores string
  23. Camion::Camion(string marcaCam, string modeloCam,string colorCam)
  24. {
  25.   marcaCamion = marcaCam;
  26.   modeloCamion = modeloCam;
  27.   colorCamion = colorCam;
  28. }
  29.  
  30. //Funciones set
  31. void Camion::setIdCamion(int idCam)
  32. {
  33.     idCamion = idCam;
  34. }
  35.  
  36. void Camion::setCilindrajeCamion(int cilindrajeCam)
  37. {
  38.     cilindrajeCamion = cilindrajeCam;
  39. }
  40.  
  41. void Camion::setNPuertasCamion(int puertasCam)
  42. {
  43.     nPuertasCamion = puertasCam;
  44. }
  45.  
  46. void Camion::setanioCamion(int anioCam)
  47. {
  48.     anioCamion = anioCam;
  49. }
  50.  
  51. void Camion::setPrecioCamion(double precioCam)
  52. {
  53.     precioCamion = precioCam;
  54. }
  55.  
  56. void Camion::setMarcaCamion(string marcaCam)
  57. {
  58.     marcaCamion = marcaCam;
  59. }
  60.  
  61. void Camion::setModeloCamion(string modeloCam)
  62. {
  63.     modeloCamion = modeloCam;
  64. }
  65.  
  66. void Camion::setColorCamion(string colorCam)
  67. {
  68.     colorCamion = colorCam;
  69. }
  70.  
  71. //Funciones get
  72. int Camion::getIdCamion() const
  73. {
  74.    return idCamion;
  75. }
  76.  
  77. int Camion::getCilindrajeCamion() const
  78. {
  79.    return cilindrajeCamion;
  80. }
  81.  
  82. int Camion::getnPuertasCamion() const
  83. {
  84.    return nPuertasCamion;
  85. }
  86.  
  87. int Camion::getanioCamion()const
  88. {
  89.    return anioCamion;
  90. }
  91.  
  92. double Camion::getPrecioCamion() const
  93. {
  94.       return precioCamion;
  95. }
  96.  
  97. string Camion::getMarcaCamion() const
  98. {
  99.       return marcaCamion;
  100. }
  101.  
  102. string Camion::getModeloCamion() const
  103. {
  104.       return modeloCamion;
  105. }
  106.  
  107. string Camion::getColorCamion() const
  108. {
  109.       return colorCamion;
  110. }

//ListaCamiones.cpp
Código
  1. #ifndef LISTADECAMIONES_H
  2. #define LISTADECAMIONES_H
  3. #include "Camion.h"
  4. #define MAXIMO 100
  5.  
  6. class listaDeCamiones
  7. {
  8.      //Variables para esta clase
  9.      Camion Camiones[MAXIMO];
  10.      int nCamiones;
  11.  
  12.      void listaDeCamiones::ingresarCamion()
  13.      {
  14.           int idCam, cilindrajeCam, nPuertasCam, anioCam;
  15.           string marcaCam, modeloCam, colorCam;
  16.           double precioCam;
  17.  
  18.           nCamiones =0; //Inicializo variable nCamiones.
  19.  
  20.           //If No sobre pase la cantidad de camiones
  21.           if (nCamiones < MAXIMO)
  22.           {
  23.            system("cls");
  24.            cout << "Ingrese los datos del camion\n";
  25.            cout << "Ingrese el ID del camion: ";
  26.            cin  >> idCam;
  27.  
  28.            cout << "Ingrese el cilindraje del camion: ";
  29.            cin  >> cilindrajeCam;
  30.  
  31.            cout << "Ingrese el numero de puertas: ";
  32.            cin  >>  nPuertasCam;
  33.  
  34.            cout << "Ingrese el año del Camion: ";
  35.            cin  >> anioCam;
  36.  
  37.            cout << "Ingrese el presio del camion: ";
  38.            cin  >> precioCam;
  39.  
  40.            cout << "Ingrese la Marca del Camion: ";
  41.            cin  >> marcaCam;
  42.  
  43.            cout << "Ingrese el Modelo del camion: ";
  44.            cin  >> modeloCam;
  45.  
  46.            cout << "Ingrese el color del camion: ";
  47.            cin  >> colorCam;
  48.  
  49.            //Instancia de camion y separado por cada constructo    
  50.            Camion *nuevoCamion1 = new Camion(idCam, cilindrajeCam, nPuertasCam, anioCam);
  51.            Camion *nuevoCamion2 = new Camion(precioCam);
  52.            Camion *nuevoCamion3 = new Camion(marcaCam, modeloCam, colorCam);
  53.  
  54.            //Añade al arreglo y lo actualiza                                        
  55.            Camiones[nCamiones++] = new_nuevoCamion;
  56.            cout << endl <<"Los datos del camion fueron ingresados correctamente\n";
  57.            }
  58.  
  59.        else
  60.        {
  61.         system("cls");
  62.         cout << "Ya no hay espacio disponible para mas camiones\n";
  63.        }
  64.     }
  65. };
  66.  
  67. #endif
//Esta parte ya la había probado y estas en lo correcto no tira error de esa forma.
Código
  1. Camion *nuevoCamion1 = new Camion(idCam, cilindrajeCam, nPuertasCam, anioCam);
  2.            Camion *nuevoCamion2 = new Camion(precioCam);
  3.            Camion *nuevoCamion3 = new Camion(marcaCam, modeloCam, colorCam);

//Ahora el error es acá. Entonces eso quiere decir que ahora tendré que crear un arreglo y que lo actualice de acuerdo a sus argumentos.
Código
  1. Camiones[nCamiones++] = new_nuevoCamion1;
  2. Camiones[nCamiones++] = new_nuevoCamion2;
  3. Camiones[nCamiones++] = new_nuevoCamion3;

//En esta parte tambien pense lo mismo y era lo que preguntaba mas arriba que si //era asi que es lo que tu mecomentas.
Código
  1. Camion nuevoCamion* = new Camion(idCam, cilindrajeCam, nPuertasCam, anioCam);


En cuanto a la liberación de memoria tengo estas funciones y hay una donde lo hace lo tengo en mente pero no puedo implementarlas si no puedo hacer la primera función que es la de ingresarlos porque estas irían en listaCamiones.Y tengo claro que cambiaran por supuesto y que tengo que arreglarlos también.

Código
  1. //Muestra los datos del camion
  2. void Camion::flistaDeCamiones()
  3. {
  4.     if (cantidadDeCamiones==0)
  5.     {
  6.       system("cls");
  7.       cout<<"No se a registrado ninguna Camion todavía"<<endl;
  8.     }
  9.       else
  10.       {
  11.           cout<<"..:::Lista de Camiones:::.."<<endl<<endl;
  12.           cout << setw(10)<<"Id Camion"<<setw(15)<<"Modelo"<<setw(15)<<"marca"<<endl;
  13.           cout<<"================================================="<<endl;
  14.  
  15.           //Imprimmir todos los camiones almacenadas en el arreglo
  16.           for (int i=0; i<cantidadDeCamiones; i++)
  17.           {
  18.             listaDeCamiones[i]->imprimir(); //PROBLEMA Y NO LO IDENTIFICO
  19.           }
  20.           cout<<endl<<"*******Fin de la lista **********"<<endl<<endl;
  21.       }
  22. }
  23. //Busca ese camion
  24. int Camion::buscarCamion(int codigo)
  25. {
  26.    for (int i=0; i < cantidadDeCamiones; i++)
  27.    {
  28.        if(listaDeCamiones[i]->getIdCamion() == codigo)
  29.        {
  30.          return i;
  31.        }
  32.    }
  33.    return -1;
  34. }
  35.  
  36. //Modifica ese Camion.
  37. void Camion::modificarCamion()
  38. {
  39.     if (cantidadDeCamiones == 0)
  40.     {
  41.       system("cls");
  42.       cout << "No se ha registrado ningun camion tadavia\n";
  43.     }
  44.     else
  45.     {
  46.         cout << "Modificar Camion\n\n";
  47.         int codigoCamion;
  48.         cout << "Ingrese el codigo del camion: ";
  49.         cin >> codigoCamion;
  50.  
  51.         int ubicacion = buscarCamion(codigoCamion);
  52.         if (ubicacion == -1)
  53.         {
  54.           cout << "Lo sentimos ese codigo del camion no existe\n";
  55.         }
  56.         else
  57.         {
  58.             cout << "El codigo se encontro\n\n";
  59.             cout << setw(10)<<"Id"<<setw(15)<<"Modelo"<<setw(15)<<"marca"<<endl;
  60.             cout<<"================================================="<<endl;
  61.  
  62.             listaDeCamiones[ubicacion]->imprimir();
  63.             cout << "\n\n";
  64.             cout  << "Ingrese los nuevos datos del Camion\n\n";
  65.  
  66.             cout <<  "Marca";
  67.             cin  >> marcaCamion;
  68.  
  69.             cout << "Modelo del camion: ";
  70.             cin  >> modeloCamion;
  71.  
  72.             cout << "Año del Camion: ";
  73.             cin  >> anioCamion;
  74.  
  75.             cout << "Cilindraje del camion: ";
  76.             cin  >> cilindrajeCamion;
  77.  
  78.             cout << "numero de puertas: ";
  79.             cin  >>  nPuertasCamion;
  80.  
  81.             cout << "Color del camion: ";
  82.             cin  >> colorCamion;
  83.  
  84.             cout << "Presio del camion: ";
  85.             cin  >> precioCamion;
  86.  
  87.             listaDeCamiones[ubicacion]->setMarcaCamion(marcaCamion);
  88.             listaDeCamiones[ubicacion]->setModeloCamion(modeloCamion);
  89.             listaDeCamiones[ubicacion]->setanioCamion(anioCamion);
  90.             listaDeCamiones[ubicacion]->setCilindrajeCamion(cilindrajeCamion);
  91.             listaDeCamiones[ubicacion]->setNPuertasCamion(nPuertasCamion);
  92.             listaDeCamiones[ubicacion]->setColorCamion(colorCamion);
  93.             listaDeCamiones[ubicacion]->setPrecioCamion(precioCamion);
  94.  
  95.             cout << "El camion fue modificado Exitosamente.\n";
  96.         }
  97.     }
  98. }
  99.  
  100. void Camion::eliminarCamion()
  101. {
  102.     if (cantidadDeCamiones == 0)
  103.     {
  104.       system("cls");
  105.       cout << "No se ha registrado ningun camion tadavia\n";
  106.     }
  107.     else
  108.     {
  109.         cout << "Eliminar Camion\n\n";
  110.         int codigoCamion;
  111.         cout << "Ingrese el codigo a eliminar: ";
  112.         cin >> codigoCamion;
  113.  
  114.         int ubicacion = buscarCamion(codigoCamion);
  115.         if (ubicacion == -1)
  116.         {
  117.           cout << "Lo sentimos ese codigo del camion no existe\n";
  118.         }
  119.         else
  120.         {
  121.             cout << "El codigo se encontro\n\n";
  122.             cout << setw(10)<<"Id"<<setw(15)<<"Modelo"<<setw(15)<<"marca"<<endl;
  123.             cout<<"================================================="<<endl;
  124.  
  125.             listaDeCamiones[ubicacion]->imprimir();
  126.             cout << "\n\n";
  127.  
  128.             cout << "Presione enter para eliminar ese camion\n\n";
  129.             system("pause");
  130.  
  131.             //Pasa a eliminar usando una copia del arreglo
  132.             Camion**temporalListaDeCamiones = new Camion*[Maximo];
  133.             int temporalCantidadDeCamiones = 0;
  134.  
  135.             //Se copia el arreglo en otro arreglo exepto el que se quiere eliminar
  136.             for(int i =0; i < cantidadDeCamiones; i++)
  137.             {
  138.               if(i!=ubicacion)
  139.               {
  140.                 temporalListaDeCamiones[temporalCantidadDeCamiones] = new Camion(listaDeCamiones[i]->getIdCamion(),
  141.                                                                                  listaDeCamiones[i]->getCilindrajeCamion(),
  142.                                                                                  listaDeCamiones[i]->getnPuertasCamion(),
  143.                                                                                  listaDeCamiones[i]->getanioCamion(),
  144.                                                                                  listaDeCamiones[i]->getPrecioCamion(),
  145.                                                                                  listaDeCamiones[i]->getMarcaCamion(),
  146.                                                                                  listaDeCamiones[i]->getModeloCamion(),
  147.                                                                                  listaDeCamiones[i]->getColorCamion());
  148.                 temporalCantidadDeCamiones++;
  149.               }//Fin if
  150.             }//Fin for
  151.  
  152.             //Limpio la memoria usada por el arreglo principal de camiones
  153.             for(int i=0; i<cantidadDeCamiones; i++)
  154.             {
  155.               listaDeCamiones[i]->~Camion();
  156.             }
  157.  
  158.             //copia el arreglo temporal al principio
  159.             cantidadDeCamiones = 0;
  160.             for(int i =0; i<temporalCantidadDeCamiones; i++)
  161.             {
  162.                listaDeCamiones[cantidadDeCamiones] = new Camion(temporalListaDeCamiones[i]->getIdCamion(),
  163.                                                                 temporalListaDeCamiones[i]->getCilindrajeCamion(),
  164.                                                                 temporalListaDeCamiones[i]->getnPuertasCamion(),
  165.                                                                 temporalListaDeCamiones[i]->getanioCamion(),
  166.                                                                 temporalListaDeCamiones[i]->getPrecioCamion(),
  167.                                                                 temporalListaDeCamiones[i]->getMarcaCamion(),
  168.                                                                 temporalListaDeCamiones[i]->getModeloCamion(),
  169.                                                                 temporalListaDeCamiones[i]->getColorCamion());
  170.                cantidadDeCamiones++;
  171.             }//Fin for
  172.             cout << "El camion fue eliminado exitosamente\n\n";
  173.         }//fin else
  174.     }
  175.  
  176. }
  177.  
  178. //Imprime los datos del Camion
  179. void Camion::imprimir()
  180. {
  181.     cout<<setw(10)<<idCamion<<setw(15)<<modeloCamion<<setw(15)<<marcaCamion<<endl;
  182. }


Título: Re: El for no me hace su funcion?
Publicado por: eferion en 5 Febrero 2014, 13:00 pm
Veo que te bailan un poco los conceptos. vamos por partes.

1. Constructores (parte1)

Al igual que los seres vivos ( con perdón de las reencarnaciones ) solo nacen una vez y en ese proceso ya nacen con todo, los objetos sólo se pueden crear una vez.

Cada vez que tu llamas a un constructor estás creando un objeto nuevo y diferente de los ya existentes.

El siguiente código crea tres camiones diferentes:

Código
  1. //Instancia de camion y separado por cada constructo    
  2.            Camion *nuevoCamion1 = new Camion(idCam, cilindrajeCam, nPuertasCam, anioCam);
  3.            Camion *nuevoCamion2 = new Camion(precioCam);
  4.            Camion *nuevoCamion3 = new Camion(marcaCam, modeloCam, colorCam);

Imagino que tú ahí estás intentando asignar todas las propiedades al mismo elemento... eso se hace con los getters y los setters que has implementado.

Código
  1. Camion* nuevoCamion = new Camion( );
  2. nuevoCamion->setId( idCam );
  3. nuevoCamion->setCilindraje( cilindrajeCam );
  4. nuevoCamion->setNPuertas( nPuertasCam );
  5. // ...

Fíjate de paso que no he dicho "setIdCamion" ni "setCilindrajeCamion"... si la clase se llama camión es redundante y totalmente innecesario que pongas el sufijo "Camion" a todos los miembros de la clase... pero eso lo tratamos más adelante para no desviarnos.

El caso es que quizás es una buena práctica que el constructor de una clase reciba únicamente aquella información que es necesaria desde un primer momento para el buen funcionamiento del código. En tu caso, la clase Camion puede funcionar perfectamente si todos sus elementos tienen valores por defecto, luego con gestionar el constructor por defecto te sobra y te basta.

No tengas miedo a que esta forma de pensar te obligue a tener 10 líneas más de código... créeme si te digo que hay malas prácticas que generan muchas más líneas de código que además suele ser bastante ilegible.

Además, no he podido evitar fijarme en la siguiente línea:

Código
  1. temporalListaDeCamiones[temporalCantidadDeCamiones] = new Camion(listaDeCamiones[i]->getIdCamion(),
  2.                                                                                  listaDeCamiones[i]->getCilindrajeCamion(),
  3.                                                                                  listaDeCamiones[i]->getnPuertasCamion(),
  4.                                                                                  listaDeCamiones[i]->getanioCamion(),
  5.                                                                                  listaDeCamiones[i]->getPrecioCamion(),
  6.                                                                                  listaDeCamiones[i]->getMarcaCamion(),
  7.                                                                                  listaDeCamiones[i]->getModeloCamion(),
  8.                                                                                  listaDeCamiones[i]->getColorCamion());

Resulta que tú aquí estás intentando hacer una copia de un objeto ya existente. Los chicos que diseñaron C++ eran bastante listos y ya pensaron en esta posibilidad y la incorporaron al lenguaje... estamos hablando del constructor copia.

El constructor copia se implementa por defecto en tooooodas las clases de C++... esto quiere decir que mientras la clase en cuestión no utilice memoria dinámica en sus miembros el constructor que se genera por defecto es perfectamente válido... aunque eso no quita que te apetezca implementarlo tu explícitamente para aprender, por optimización, por seguridad o por lo que sea.

El constructor copia, si lo defines explícitamente, debería tener la siguiente firma.

Código
  1. class Camion
  2. {
  3.  public:
  4.    Camion( const Camion& );
  5. };

Y en su implementación deberías realizar la tarea de copiar los datos de un objeto en otro:

Código
  1. Camion::Camion( const Camion& otro )
  2. {
  3.  idCamion = otro.idCamion;
  4.  cilindrajeCamion = otro.cilindrajeCamion;
  5.  // ...
  6. }

Con esto, tu línea puede quedar reducida a algo tan simple como:

Código
  1. temporalListaDeCamiones[temporalCantidadDeCamiones] = new Camion( *listaDeCamiones[i] );

o incluso, si temporalListaDeCamiones fuese un vector, el código quedaría aún más simple:

Código
  1. temporalListaDeCamiones.push_back( new Camion( *listaDeCamiones[ i ] );

Resumiendo, tu clase debería tener el constructor por defecto y, si te apetece implementarlo explícitamente, el constructor copia... el resto de constructores puedes obviarlos:

Código
  1. class Camion
  2. {
  3.  public:
  4.    Camion( );
  5.    Camion( const Camion& otro );
  6. };

2. Constructores (parte 2)

Cuando tú reservas memoria con un new, la memoria que el sistema te da viene "tal cual", es decir, no hay un proceso de limpieza que deje la memoria lista como si fuese a estrenar. Mas bien te encuentras con que la memoria que te ha dado el sistema tiene basura no es sino la información que otra aplicación, en su momento, escribió en esa posición y ahora ya no la usa.

Es tarea del que programa una clase inicializar toda la memoria utilizada por dicha clase. Esto quiere decir, en otras palabras, que has de dar valores por defectos a todas las variables miembros, al menos a aquellas que no sean clases.

El sitio adecuado para hacer esta tarea es en el constructor ( o constructores ). Recuerda que la llamada a un constructor cualquiera, por ejemplo al constructor copia, no implica una llamada al constructor por defecto.

Código
  1. Camion::Camion( )
  2. {
  3.  idCamion = 0;
  4.  cilindrajeCamion = 0;
  5.  // ...
  6. }

Con este trabajo te aseguras que todos los objetos que se creen van a tener valores válidos SIEMPRE, que es el objetivo a conseguir. Un objeto con valores no válidos se vuelve inestable y da problemas, quedas avisado.

3. Clases (parte3)

En este apartado me voy a centrar en la nomenclatura utilizada para los miembros de la clase.

Si bien es algo meramente estético no deja de ser importante para facilitar la lectura del código.

Como te comenté anteriormente no tiene sentido que un método de la clase Camion contenga el sufijo Camion. Si por ejemplo tu dices:

Código
  1. camion->setNPuertas( X );

Se presupone que lo que vas a indicar es el número de puertas del camión... luego el sufijo "Camion" sobra.

Con esta premisa, los setters deberían tener más o menos esta forma:

Código
  1. class Camion
  2. {
  3.  public:
  4.      void setId(int);         //Devuelve el Id del Camion.
  5.      void setCilindraje(int); //Devuelve el cilindrage del camion
  6.      void setNPuertas(int);   //Devuelve el numero de puertas del camion
  7.      void setanio(int);       //Devuelve el año del camion
  8.      void setPrecio(double);  //Devuelve el precio del camion
  9.      void setMarca(string);   //Devuelve la marca del camion
  10.      void setModelo(string);  //Devuelve el modelo del camion
  11.      void setColor(string);   //Devuelve el color del camion
  12. };

Aunque se les podría dar una vuelta de tuerca más.

Si has leído todo hasta aquí ya te habrás enterado de que existe el constructor copia. En tu código actual, cuando tu haces:

Código
  1. camion->setMarca( loquesea );

estás creando una copia de loquesea y esa copia será la que se use dentro de la función... esto supone una carga adicional y absurda, pues se crea un objeto copia con cada llamada.

Es una buena costumbre que las clases se pasen como referencias constantes. De esta forma evitas tener que crear un objeto temporal perfectamente evitable.

El cambio es relativamente sencillo:

Código
  1. class Camion
  2. {
  3.  public:
  4.      void setId(int);         //Devuelve el Id del Camion.
  5.      void setCilindraje(int); //Devuelve el cilindrage del camion
  6.      void setNPuertas(int);   //Devuelve el numero de puertas del camion
  7.      void setanio(int);       //Devuelve el año del camion
  8.      void setPrecio(double);  //Devuelve el precio del camion
  9.      void setMarca( const string& );   //Devuelve la marca del camion
  10.      void setModelo( const string& );  //Devuelve el modelo del camion
  11.      void setColor( const string& );   //Devuelve el color del camion
  12. };

Y además tiene la ventaja de que las llamadas a las funciones son exactamente iguales que antes!!!

Ponerle la etiqueta const indica que el objeto que se pasa como argumento no va a ser modificado... una referencia es similar a un puntero y aquí tienes un ejemplo:

Código
  1. void func( int& numero )
  2. {
  3.  numero = 10;
  4. }
  5.  
  6. void main( )
  7. {
  8.  int num = 0;
  9.  
  10.  std::cout << num << std::endl;
  11.  func( num );
  12.  std::cout << num << std::endl;
  13. }

El resultado de ejecutar este programa es el siguiente:

Código:
0
10

4. Principio de responsabilidad única

Cada clase y cada método que programes debería regirse por este principio, por tu bien.

El principio se basa en que cada función debería dedicarse a una única tarea. Una clase que permite imprimir por pantalla no debería controlar el estado de la tarjeta de sonido, por ejemplo.

En tu caso, la clase Camion tiene dos tareas diferentes:

* Gestiona los datos de un camion
* Gestiona una lista de camiones

Esta parte de tu código en la clase Camion

Código
  1.  private:
  2.      Camion**listaDeCamiones;
  3.      int cantidadDeCamiones;

Debes eliminarla. Si quieres gestionar una lista de camiones, estupendo... pero que no sea la clase Camion la encargada de dicha gestión. Si es necesario que de dicha gestión se encargue una clase, creas una clase nueva.

Otra forma de violar este principio lo encontramos en este otro ejemplo que te vas a encontrar más veces de las que piensas:

Código
  1. class Persona
  2. {
  3.  public:
  4.    void SetDatos( )
  5.    {
  6.      std::cout << "Introduce el nombre: ";
  7.      std::cin >> nombre;
  8.      std::cout << "Introduce su edad: ";
  9.      std::cin >> edad;
  10.    }
  11.  
  12.  private:
  13.    std::string nombre;
  14.    int edad;
  15. };

En este caso, la clase Persona no solo gestiona los datos de una persona, también se encarga de comunicarse con el usuario para pedirle datos... mala solución.

Lo mismo esto te resulta familiar. Tu clase listaDeCamiones infringe este principio.

5. Contenedores

Insisto, si no es un requisito del ejercicio, usa contenedores en vez de arreglos. Salvo que quieras o tengas que practicar, no es necesario reinventar la rueda con cada programa... no es práctico.

Los contenedores te permiten almacenar listas de elementos de formas diversas: ordenados, sin ordenar, sin duplicados, con índice, ...

Además con los contenedores reduces las probabilidades de acceder a posiciones de memoria que no debes, te proporcionan información sobre el número de elementos que tienen, pueden crecer dinámicamente sin que tú tengas que preocuparte por ello...

Como norma general, todo son ventajas.

6. Otras cuestiones

Deberías leerte y reorganizar tu código. La última secuencia de código que has puesto deberían formar parte de la clase listaDeCamiones... ya que es esta clase la que gestiona la lista de camiones.

Por el momento creo que ya es bastante para asimilar, dedica el tiempo necesario a arreglar el código y no intentes ir rápido... las prisas no son buenas.


Título: Re: El for no me hace su funcion?
Publicado por: nolasco281 en 5 Febrero 2014, 18:00 pm
Entendí la mayoría de las cosas que me dijiste, ya lo he leído como 30,35 veces

Y la funcion listaDeCamiones::ingresarCamion() ya la probe y esta bien ya no tengo problema.

Código
  1. Camion* nuevoCamion = new Camion( );
  2.            nuevoCamion->setId(idCam);
  3.            nuevoCamion->setCilindraje(cilindrajeCam);
  4.            nuevoCamion->setNPuertas(nPuertasCam);
  5.            nuevoCamion->setanio(anioCam);
  6.            nuevoCamion->setPrecio(precioCam);
  7.            nuevoCamion->setMarca(marcaCam);
  8.            nuevoCamion->setModelo(modeloCam);
  9.            nuevoCamion->setColor(colorCam);
  10.  
  11.            //Añadiendo los camiones a nCamiones a arreglo y lo actualiza
  12.            //recorar nuevoCamion instancia de Camion                                        
  13.            Camion[nCamiones++] = nuevoCamion;

Y mis ultimas dos dudas.

1. Pero para ir guardando los registros del cada camion. estaria bien asi ya que todavía no lo estoy mostrando solo guardanlos.


Código
  1. Camion[nCamiones++] = nuevoCamion; //Tambien esta donde le mando los argumentos a los metodos para que se observe mejor.

2. Una anotación que me llamo mucho la atención es de la clase persona. Eso me hace pensar, no sé si estoy en lo correcto que debería de crear la de encabezado que gestiona los datos de una persona. y la de implementación que se encarga de comunicarse con el usuario. .

En mi caso sería una para que me gestione los datos de listaDeCamiones la .h y la otra que se comunique con el usuario .cpp

Y no sé si estoy mal lo dices para mantener la robustez de un software y la legibilidad del mismo.

Muchas gracias por su ayuda enserio mil gracias me han ayudado a mejorar en un 100% en cuanto al manejo de código y a las buenas practicas. Siempre las tomo y más cuando te ayudan a agilizar y sobretodo que otras personas lo entiendan.

agradezco a primeramente a eferion y a yoel_alejandro. por tomarce todo ese tiempo para ayudarme y con eso doy por cerrado este tema.

y me dare la tarea de los demas hacerlo yo, ya que no veo mucha dificulta haciendo el primero. tanto con vectores como con arreglo de apuntadores. para entender este tema mejor.

Y gracias de nuevo un saludo a todos.


Título: Re: El for no me hace su funcion?
Publicado por: eferion en 6 Febrero 2014, 08:22 am
1. Pero para ir guardando los registros del cada camion. estaria bien asi ya que todavía no lo estoy mostrando solo guardanlos.


Código
  1. Camion[nCamiones++] = nuevoCamion; //Tambien esta donde le mando los argumentos a los metodos para que se observe mejor.

Si tú en tu código tienes algo tal que:

Código
  1. class Camion ...

Ni puedes ni debes usar la palabra Camion para identificar un array, vector o arreglo de camiones.

Que haya nombres que colisionen ( es decir, que sean iguales ) y sirvan para cosas diferentes causa confusión a la hora de revisar el código y de encontrar errores.

Además, lo de nCamiones++... eso solo es necesario si usas arreglos al estilo de C, con contenedores no suele ser necesaria esa variable.

2. Una anotación que me llamo mucho la atención es de la clase persona. Eso me hace pensar, no sé si estoy en lo correcto que debería de crear la de encabezado que gestiona los datos de una persona. y la de implementación que se encarga de comunicarse con el usuario. .

En mi caso sería una para que me gestione los datos de listaDeCamiones la .h y la otra que se comunique con el usuario .cpp

A lo que me refería con el ejemplo de la clase Persona es que hay que separar actividades que no tienen nada que ver entre sí; me explico:

Tu diseñas una clase, por ejemplo una llamada "Camion"... y le pones un método para crear instancias de esta clase que le pide al usuario vía consola los datos requeridos para su creación. Pasa el tiempo y te llega un encargo para que ahora pueda funcionar con una interfaz de ventanas... ¿que haces en este caso? Al final te toca modificar una clase que ya funciona debido a un mal diseño.

Código
  1. // Diseño malo
  2.  
  3. class Camion
  4. {
  5.  public:
  6.    Camion( );
  7.    Camion( const Camion& );
  8.    virtual ~Camion( );
  9.  
  10.    void SetId( int id );
  11.    void SetMatricula( const std::string& matricula );
  12.  
  13.    int GetId( ) const;
  14.    std::string GetMatricula( ) const;
  15.  
  16.   void PideDatos( ); // funcion conflictiva
  17. };

En cambio imagínate que en vez de optar por ese diseño "rápido" y problemático, sacas de "Camion" la función que pide los datos al usuario y la dejas en una clase independiente... en este caso para cambiar la interfaz con el usuario no hace falta tocar para nada una clase que funciona como es el caso de Camion. Y no solo eso, si además has diseñado la clase con cierto cuidado puedes hasta hacer uso de polimorfismo para que tu código pueda funcionar con varias interfaces diferentes sin tener siquiera que recompilar.

Código
  1. // Diseño bueno
  2.  
  3. class Camion
  4. {
  5.  public:
  6.    Camion( );
  7.    Camion( const Camion& );
  8.    virtual ~Camion( );
  9.  
  10.    void SetId( int id );
  11.    void SetMatricula( const std::string& matricula );
  12.  
  13.    int GetId( ) const;
  14.    std::string GetMatricula( ) const;
  15. };
  16.  
  17. class Interfaz
  18. {
  19.  public:
  20.    // Funcion virtual pura, esta clase sirve para poder hacer polimorfismo
  21.    virtual Camion* PideDatos( ) = 0;
  22. };
  23.  
  24. class InterfazDOS
  25.  : public Interfaz
  26. {
  27.  public:
  28.    // Este metodo contiene la logica necesaria para comunicarse con el usuario via consola
  29.    virtual Camion* PideDatos( ) override;
  30. };
  31.  
  32. class InterfazWindows
  33.  : public Interfaz
  34. {
  35.  public:
  36.    // Este metodo contiene la logica necesaria para comunicarse con el usuario via windows
  37.    virtual Camion* PideDatos( ) override;
  38. };
  39.  
  40. Interfaz ObtenerInterfazUsuario( )
  41. {
  42.  // Estas directivas de precompilador se pueden cambiar por variables o lo que sea
  43.  // a gusto del consumidor
  44.  #ifdef _WIN32
  45.    return new InterfazWindows( );
  46.  #else
  47.    return new InterfazDOS( );
  48.  #endif
  49. }
  50.  
  51. void main( )
  52. {
  53.  Interfaz* interfaz = ObtenerInterfazUsuario( );
  54.  
  55.  // Le pedimos al usuario los datos del camion y nos da igual si
  56.  // lo hace a traves de una ventana de Windows o de una consola.
  57.  Camion* camion = interfaz->PideDatos( );
  58. }

Espero que con el ejemplo haya quedado este tema un poco más claro.

Un saludo.


Título: Re: El for no me hace su funcion? (Solucionado)
Publicado por: nolasco281 en 7 Febrero 2014, 02:36 am
Aclarado cuando termine el programa lo comparto para quien le sirva.  Y si es un poco confuso pero hai voy saludos y gracias a todos.