Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Patron prototype: como implementarlo

Estas en el tema de Patron prototype: como implementarlo en el foro de C/C++ en Foros del Web. Bueno, quise implementar el patron prototype con 2 prototipos de tv que hereda del prototipo TV. PrototipoLED y prototypePLASMA, pero no funciona. Obtengo el error ...
  #1 (permalink)  
Antiguo 04/10/2015, 05:00
Avatar de giuli956  
Fecha de Ingreso: noviembre-2012
Mensajes: 149
Antigüedad: 11 años, 5 meses
Puntos: 1
Patron prototype: como implementarlo

Bueno, quise implementar el patron prototype con 2 prototipos de tv que hereda del prototipo TV. PrototipoLED y prototypePLASMA, pero no funciona.
Obtengo el error 101 no matching function for call to `prototipoLED::prototipoLED(prototipoTV)' y luego muestra los parametros del constructor, es el tipico error de los atributos en el constructor pero no se como se resuleve...

Aqui el codigo

Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3. class prototipoTV{
  4.  
  5.       protected:
  6.       string marca;
  7.       string modelo;
  8.       string color;
  9.       int resvert;
  10.       int reshori;
  11.       string TEC;
  12.       int brillomax;
  13.       int garantia;
  14.       public:
  15.              
  16.       prototipoTV(string marcaTV,string modeloTV,string colorTV,string TECTV,
  17.       int resvertTV,int reshoriTV,int brillomaxTV,int garantiaTV){
  18.              marca=marcaTV;
  19.              modelo=modeloTV;
  20.              color=colorTV;
  21.              TEC=TECTV;
  22.              resvert=resvertTV;
  23.              reshori=reshoriTV;
  24.              brillomax=brillomaxTV;
  25.              garantia=garantiaTV;
  26.       };
  27.       virtual prototipoTV clonar();
  28.      
  29.       void setMarca(string marcaTV){this->marca=marcaTV;};
  30.       void setModelo(string modeloTV){this->modelo=modeloTV;};
  31.       void setColor(string colorTV){this->color=colorTV;};
  32.       void setTEC(string TECTV){this->TEC=TECTV;};
  33.       void setResvert(int resvertTV){this->resvert=resvertTV;};
  34.       void setReshori(int reshoriTV){this->reshori=reshoriTV;};
  35.       void setBrillomax(int brillomaxTV){this->brillomax=brillomaxTV;};
  36.       void setGarantia(int garantiaTV){this->garantia=garantiaTV;};
  37. };      
  38. class prototipoLED:public prototipoTV{
  39.       private:
  40.               int garantia;
  41.       public:
  42.            
  43.              prototipoLED::prototipoLED(string marcaTV,string modeloTV,string colorTV,string TECTV,
  44.              int resvertTV,int reshoriTV,int brillomaxTV,int garantiaTV):prototipoTV(marcaTV,modeloTV,
  45.              colorTV,TECTV,resvertTV,reshoriTV,brillomaxTV,garantiaTV){
  46.                                                                
  47.                                                                        };
  48.              void getTipoTV(){
  49.                          cout<<("soy un LED")<<endl;
  50.                          };
  51.              prototipoTV clonar(){
  52.                          //prototipoLED *LED2= new prototipoLED("A","A","A","A",1,1,1,1);
  53.                          prototipoTV *LED2= new prototipoLED(*this);
  54.                          /*LED2->setMarca(this->marca);
  55.                          LED2->setBrillomax(this->brillomax);
  56.                          LED2->setColor(this->color);
  57.                          LED2->setModelo(this->modelo);
  58.                          LED2->setReshori(this->reshori);
  59.                          LED2->setResvert(this->resvert);
  60.                          LED2->setTEC(this->TEC);
  61.                          LED2->setGarantia(this->garantia);*/
  62.                          return *LED2;
  63.                          };
  64.       };
  65. class prototipoPLASMA:public prototipoTV{
  66.       private:
  67.               int garantia;
  68.       public:
  69.          
  70.              prototipoPLASMA::prototipoPLASMA(string marcaTV,string modeloTV,string colorTV,string TECTV,
  71.              int resvertTV,int reshoriTV,int brillomaxTV,int garantiaTV):prototipoTV(marcaTV,modeloTV,
  72.              colorTV,TECTV,resvertTV,reshoriTV,brillomaxTV,garantiaTV){
  73.                                                                    
  74.                                                                        };
  75.              void getTipoTV(){
  76.                          cout<<("soy un PLASMA")<<endl;
  77.                          }
  78.              prototipoTV clonar(){
  79.                          prototipoPLASMA *PLASMA2= new prototipoPLASMA("samsung","dff","negro","IPS",1280,720,12,24);
  80.                          PLASMA2->setMarca(this->marca);
  81.                          PLASMA2->setBrillomax(this->brillomax);
  82.                          PLASMA2->setColor(this->color);
  83.                          PLASMA2->setModelo(this->modelo);
  84.                          PLASMA2->setReshori(this->reshori);
  85.                          PLASMA2->setResvert(this->resvert);
  86.                          PLASMA2->setTEC(this->TEC);
  87.                          return *PLASMA2;
  88.                          };
  89.       };
  90. class Cliente{
  91.      
  92.      
  93.    
  94.     public: static void obtenerTVs(){
  95.             prototipoLED *primerLED=new prototipoLED("samsung","dff","negro","IPS",1280,720,12,6);
  96.             prototipoPLASMA *primerPLASMA= new prototipoPLASMA("samsung","dff","negro","IPS",1280,720,12,6);
  97.             prototipoLED *listaLED[10];
  98.             prototipoPLASMA *listaPLASMA[10];
  99.             for (int x=0;x<10;x++){
  100.                        // cout<<primerLED->clonar()<<endl;  
  101.                         listaLED[x]= (prototipoLED) primerLED->clonar();
  102.                      //  listaPLASMA[x]=(prototipoPLASMA) primerPLASMA->clonar();
  103.                      
  104.                        
  105.                        listaLED[x]->getTipoTV();
  106.                    
  107.                                      };
  108.            
  109.                             };
  110.       };
  111. int main(){
  112.    
  113.     Cliente::obtenerTVs();
  114.        
  115.            system("pause");
  116.            return 0;
  117.            };

estoy probando primero con LEd para luego hacer PLASMA.
Saludos
  #2 (permalink)  
Antiguo 05/10/2015, 03:54
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Patron prototype: como implementarlo

Tienes varios errores:

Código C++:
Ver original
  1. class prototipoLED:public prototipoTV{
  2.       private:
  3.               int garantia;
  4.       public:
  5.            
  6.              prototipoLED::prototipoLED(string marcaTV,string modeloTV,string colorTV,string TECTV,

En la declaración de una clase, las funciones miembro no deben indicar el ámbito de la función prototipoLED::prototipoLED() debería ser, simplemente prototipoLED(). Lo otro déjalo para las implementaciones. ¿Por qué? Si prototipoLED tiene una clase anidada que se llama prototipoLED vas a implementar la función de esta segunda clase... la confusión está asegurada.

Código C++:
Ver original
  1. class prototipoTV{
  2.   virtual prototipoTV clonar();
  3. };

Dos cosas respecto a esta función:
  1. Si prototipoTV no va a ser una clase construible como tal, ésta función debería ser virtual pura, es decir, la declaración debería terminar con =0 y no debería poseer implementación.
  2. Si devuelves un objeto de tipo prototipoTV en vez de devolver un puntero lo que va a suceder es que al llamar a prototipoLED::clonar() vas a obtener un objeto de tipo prototipoTV que no podrás convertir a uno de tipo prototipoLED. ¿Por qué? porque al hacer:

    Código C++:
    Ver original
    1. class prototipoLED
    2. {
    3.   prototipoTV clonar()
    4.   {
    5.     prototipoTV *LED2= new prototipoLED(*this);
    6.     return *LED2; // <<< AQUI!!!
    7.   }
    8. };
    Estarás llamando al constructor copia de prototipoTV, el cual te devolverá una instancia de prototipoTV no convertible a ninguna otra clase hija. Si no entiendes este punto deberías revisar el tema del polimorfismo... el polimorfismo no funciona con objetos usados por valor.

Volviendo a la función prototipoLED::clonar()...

Código C++:
Ver original
  1. class prototipoLED
  2. {
  3.   prototipoTV clonar()
  4.   {
  5.     prototipoTV *LED2= new prototipoLED(*this);
  6.     return *LED2; // <<< AQUI!!!
  7.   }
  8. };

Otras dos cosillas:
  1. Al hacer:
    Código C++:
    Ver original
    1. new prototipoLED(*this)

    estás llamando al constructor copia de prototipoLED. Como no lo has implementado el compilador creará una versión por defecto... esta versión por defecto llamará al constructor por defecto de prototipoTV. Este último constructor copiará el valor de todos los miembros a la nueva instancia. Este detalle no suele dar problemas hasta que gestionas memoria dinámica. No es tu caso, pero ándate con ojo al usar constructores no implementados explícitamente.
  2. No se si te estás dando cuenta, pero al hacer:
    Código C++:
    Ver original
    1. return *LED2;
    Estás dejando a LED2 en el limbo, ya que has reservado memoria con new pero no has hecho ningún delete. Esto se llama fuga de memoria y es un problema muy serio en un programa. Este problema se resolverá cuando descubras que "clonar" tiene que devolver punteros.

Más cosillas. ¿Qué imaginas que estás haciendo con estas dos líneas?

Código C++:
Ver original
  1. prototipoLED *listaLED[10];
  2. prototipoPLASMA *listaPLASMA[10];

¿cada una de estas listas almacena objetos por valor? ¿referencias tal vez? ¿punteros?

Son listas de punteros, luego la siguiente línea no tiene ningún sentido:

Código C++:
Ver original
  1. listaLED[x]= (prototipoLED) primerLED->clonar();

por lo siguiente:

primerLED->clonar() devuelve un objeto por valor de tipo prototipoTV, como este objeto ya no es, a diferencia de lo que esperas, de tipo prototipoLED, el compilador tiene que llamar implícitamente al constructor prototipoLED(constructorTV) el cual no no existe porque tú no lo has implementado y porque el compilador no lo va a crear por su cuenta. Por cierto... te suena de algo este constructor?. Bueno, el caso es que después intentas almacenar un objeto por valor dentro de una lista de punteros!!!!!!

Y, por otro lado, una de las gracias de usar polimorfismo es poder usar prototipoLED y prototipoPlasma en una misma lista sin tener que preocuparte de sus diferencias internas... crear este esquema de clases para luego usar cada clase por separado no tiene absolutamente ningún sentido. Para eso usas el patrón decoración y te ahorras un montón de trabajo.

Lo suyo sería que tuvieses:

Código C++:
Ver original
  1. prototipoTV* lista[10];

Y que ahí almacenases todas las televisiones.

Y bueno, para terminar, decir que Cliente::obtenerTVs() crea dos listas de elementos pero ni limpia memoria ni devuelve dichas listas, luego acabarás creando nuevamente fugas de memoria.

Un saludo.

Etiquetas: funcion, int, patron, prototype, string
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:31.