How do I print lists with objects?

0

I am working with simple lists, we are inserting objects. But I have this code to show list that only prints values, I do not know how I do that I print objects.

This is the .cpp of the class I want to print:

/*
 * Takuilla.cpp
 *
 *  Created on: 29/10/2018
 *      Author: Fioxin
 */

#include "Takuilla.h"



void Takuilla::setCantPuestosZona(int cantPuestosZona)
{
    this->cantPuestosZona = cantPuestosZona;
}

int Takuilla::getCantPuestosZona(){
    return cantPuestosZona;
}



void Takuilla::setZona(string zona)
{
    this->zona = zona;
}

string Takuilla::getZona()
{
    return zona;
}

void Takuilla::setPrecio(float precio)
{
    this->precio = precio;
}

float Takuilla::getPrecio()
{
    return precio;
}

string Takuilla::tipoBoleto(int zona){
 string nombre;
 switch(zona){
     case 1: nombre = "Central";
         break;
     case 2:    nombre = "CentralVIP";
         break;
     case 3:    nombre = "Lateral";
         break;
     case 4:    nombre = "Gradas";
         break;
 }
 return nombre;
}

float Takuilla::precioEntrada(int zona){
    float precio;
    switch(zona){
    case 1: // zona Central;
        precio = 800;
        break;
    case 2: // Central VIP
        precio = 1000;
        break;
    case 3: // Lateral
        precio = 500;
        break;
    case 4: // Gradas
        precio = 200;
        break;
    }
    return precio;
}

Takuilla::~Takuilla() {
    // TODO Auto-generated destructor stub
}

This is the cpp of the class list:

#include "Lista.h"
#include <iostream>
#include <string>
using namespace std;


#include "Lista.h"

template <class Tipo>
nodo<Tipo>* Lista<Tipo>::ObtPrimero(){
  return Primero;
};

template <class Tipo>
void Lista<Tipo>::AsigPrimero(nodo<Tipo>* p){
     Primero=p;
};

template <class Tipo>
Lista<Tipo>::Lista()
{
     Primero=NULL;
};

template <class Tipo>
bool Lista<Tipo>::Vacia()
{
  return Primero == NULL;
};

template <class Tipo>
bool Lista<Tipo>::Llena()
{
  nodo<Tipo> *p;
  p=new nodo<Tipo>;
  if (p==NULL)
     return true;
  else
    {
      delete p;
      return false;
    }
};

template <class Tipo>
bool Lista<Tipo>::InsComienzo(Tipo Valor)
{
  Apuntador nuevo;
  if (!Llena())
     {
      nuevo=new nodo<Tipo>;
      nuevo->info=Valor;
      nuevo->prox=Primero;
      Primero=nuevo;
      return true;
     }
  else
      return false;
};

template <class Tipo>
bool Lista<Tipo>::EliComienzo(Tipo &Valor)
{
  Apuntador viejo;
  if (!Vacia())
     {
      viejo=Primero;
      Valor=viejo->info;
      Primero=Primero->prox;
      delete viejo;
      return true;
     }
  else
      return false;
};

template <class Tipo>
bool Lista<Tipo>::InsDespues(Apuntador p,Tipo Valor)
{
  Apuntador nuevo;
  if (!Llena())
      if (p==NULL)
         return false;
      else
         {
               nuevo=new nodo<Tipo>;
               nuevo->info=Valor;
               nuevo->prox=p->prox;
               p->prox=nuevo;
               return true;
         }
  else
      return false;
};

template <class Tipo>
bool Lista<Tipo>::EliDespues(Apuntador p,Tipo &Valor)
{
  Apuntador viejo;
     if (p==NULL)
         return false;
     else
        if (p->prox==NULL)
           return false;
        else
             {
                   viejo=p->prox;
                   Valor=viejo->info;
                   p->prox=viejo->prox;
                   delete viejo;
                   return true;
             };
};

template <class Tipo>
nodo<Tipo>* Lista<Tipo>::ObtProx(Apuntador p)
{
  return p->prox;
};

template <class Tipo>
void Lista<Tipo>::AsigProx(Apuntador p,Apuntador q)
{
  p->prox=q;
};

template <class Tipo>
Tipo Lista<Tipo>::ObtInfo(Apuntador p)
{
  return p->info;
};

template <class Tipo>
void Lista<Tipo>::AsigInfo(Apuntador p,Tipo Valor)
{
  p->info=Valor;
};

template <class Tipo>
Lista<Tipo>::~Lista()
{
  nodo<Tipo> *p;
  while (!Vacia())
   {
        p=Primero->prox;
        delete Primero;
        Primero=p;
   };
};


/*template <class Tipo>
int Lista<Tipo>::Contar()

{
   int cont=0;
   nodo<Tipo> *ap;
   if(!Vacia())
{
    ap= ObtProx(Primero);
while(ap!=NULL)
{
    ap=ObtProx(ap);
    cont++;
};
    return cont;
}
else
return 0;
}
*/
template <class Tipo>
int Lista<Tipo>::Contar(){
    nodo<Tipo>* p;
    int cont = 0;
    p = Primero;
    while(p != NULL){
        cont++;
        p = p->prox;
    }
    return cont;
}

template <class Tipo>
nodo<Tipo>* Lista<Tipo>::Buscar(Tipo Valor)
{
    nodo<Tipo> *aux =NULL;
    Apuntador ap;
    if(ap!=NULL){
        aux=ap;
        while(aux !=NULL){
            if (aux->info==Valor){
                return aux;
            }
            aux = aux->prox;
        }
    }

}

template <class Tipo>
void Lista<Tipo>::pasarListaAux(Lista<Tipo> &listaFuente, Lista<Tipo> &listaDestino) {
    Tipo valor;
    int tamano = 0;
    tamano = listaFuente.Contar();
    for(int i = 0; i < tamano; i++){
        listaFuente.EliComienzo(valor);
        listaDestino.InsComienzo(valor);
    }
}

template <class Tipo>
void Lista<Tipo>::mostrarLista(){
  nodo<Tipo> *actual = new nodo<Tipo>;
      actual = Primero;

      while(actual != NULL ){
          cout <<  actual;
          actual = actual->prox;

      }
}
/*
template <class Tipo>
bool Lista<Tipo>::Insertar(Tipo Valor){
    Apuntador ap  = new nodo<Tipo>;


    nodo *aux1= Primero;

    if(!Llena()){
        ap->info=Valor;
        ap->prox=Primero;
        Primero=ap;
    }
    else{
        ap->info=Valor;
        Primero= ap;
        ap->prox=aux1;
    }*/

And here the main :

#include "Lista.cpp"
#include <stdlib.h>
#include <iostream>
#include "Takuilla.h"
#include "Lista.h"
#include "VGeneral.h"

int main(){

    Lista<Takuilla> tk;
    Takuilla Tak;
    VGeneral vg;
    int opc,zona,cantEn,resp;
    float precio;
    string nombreZ,codigo;
    do{

         cout<<"\t ------Bienvenido--- \n";
         cout<<"1. Incluir Takuilla\n";
         cout<<"2. Consultar Takuillas\n";
         cout<<"3. Modificar Takuilla\n";
         cout<<"4. Eliminar Takuilla\n";
         cout<<"5. Salir\n";
         cin>>opc;
         system("cls");

         switch(opc){
         case 1:
             do {
                 if(tk.Llena()){
                     cout<<"\tLista llena. Elimine Elementos para insertar\n";
                 }
             codigo = vg.LeerString("\t Hola Introduzca el codigo de la takuilla\n");
             //buscar el codigo
             zona = vg.LeerNro("Ingrese el tipo de entrada kue vendera \n 1. Central \n 2. Central VIP \n 3. Latera \n 4. Gradas\n");
             precio = Tak.precioEntrada(zona);
             nombreZ = Tak.tipoBoleto(zona);
             cantEn = vg.LeerNro("Cantidad de Entrada kue vendera?");
             Tak.setZona(nombreZ);
             Tak.setPrecio(precio);
             Tak.setCantPuestosZona(cantEn);
             tk.InsComienzo(Tak);
             resp = vg.LeerValidarNro("Desea Agregar otra takuilla? 1.Si 2.No",1,2);
            }while(resp == 1);
             break;

         case 2:
             if(tk.Llena()){
                 cout<<"No hay elementos para mostrar";
             }
             tk.mostrarLista();

             vg.Pausa();
             break;
         case 3:
             break;
         case 4:
             break;
         case 5:
             break;
         }
    }while(opc !=6);
    return 0;
}
  

What the professor asked to print is the list of all the   lockers or a list with all the lockers.

    
asked by XIangn Rodriguez 06.11.2018 в 02:27
source

1 answer

0

Before you start

First of all, the templates are slightly different from the normal classes. Since a template is abstract the compiler, when it encounters one, does not generate code because what code should it generate? All possible specializations? Just a few? What if the template is going to be used with classes that you do not know yet? Too many unanswered questions.

The fact is that the compiler, when the declaration of a template is found, points it to a list ... and does nothing else with it until it begins to find uses of it. At that moment generates the specializations that are needed at all times.

Because of this feature:

  • Only the minimum essential code is generated ... if a method of a class based on templates is not used, it is not implemented.
  • If a specialization is not used, it does not generate code either.
  • The compiler needs to know the implementation of the template at all times, if it will not have problems to generate the corresponding code.

The last section is the important one and, in order not to begin to put theory into the answer, we will leave it in the case of templates, declaration and implementation must be in the same file . You are separating Lista in two files and I already tell you that it will not work for you.

Your problem

The problem is because you expect a template (which is abstract) to have a specific behavior, that is, to know in advance what type it will contain:

In the mostrarLista function you do not have Takuilla but Tipo . And what information does Tipo give us? absolutely none. We do not know what it could be and as soon as it can become Takuilla as in int or void* ... go know.

On a personal basis, it does not seem right that this method belongs to the list. It does not seem right to me because I do not think there is only one way to print the list of elements (sometimes you'll want to show more information and others less) and that configuration becomes more complicated by entering the method in Lista .

On the other hand, I do not know if it is a requirement of the exercise, so let's assume that it is. Under this premise, how can we get Lista to know how to print the object it contains?

Lista is abstract, so we can not we can call any method of Takuilla . If we do, we are loading the template ... it will not work with any class that does not implement the methods we use.

The solution is to provide this mechanism from outside and one possibility is to use an additional template. This template is specialized for the types that we need to print. The list will use these templates to print the list:

List.h

// Implementación por defecto
template<class T>
struct ListTraits
{
  void PrintObject(std::ostream & os, T const& item)
  {
    os << item << '\n';
  }
};

// ...

template <class Tipo>
void Lista<Tipo>::mostrarLista(){
  nodo<Tipo> *actual = Primero;

  ListTraits<Tipo> traits;
  while(actual != NULL ){
    traits.PrintObject(cout,actual->info);
  }
}

Takuilla.h

#include "Lista.h"

class Takuilla
{
  // ...
};

// Especialización para el caso de Takuilla
template<>
struct ListTraits<Takuilla>
{
  void PrintObject(std::ostream & os, Takuilla const& item)
  {
    os << "Zona: " << item.getZona()
       << " - Precio: " << item.getPrecio()
       << '\n';
  }
};

Of course in ListTraits you can add more information if you need it.

The great advantage of this system is that it will adapt automatically to the type of object contained in Lista .

    
answered by 07.11.2018 в 08:40