lunes, 2 de julio de 2018

C++ Composición


COMPOSICIÓN

La composición, es una forma común de reutilizar software, pudiendo utilizar objetos como miembros de otras clases.  En palabras más sencillas, es como utilizar clases como si estas fuesen un tipo de variable.

Para entender un poco más la composición, debemos pensar que en nuestro mundo, muchos objetos son construidos usando objetos más pequeños. Por ejemplo un auto es ensamblado usando ruedas, motor, asientos, carrocería, entre otros.

Para el siguiente ejemplo, se utilizarán dos archivos de encabezado .h, dos archivos  con funciones .cpp y un archivo principal (main) .cpp
Para esto, vamos a crear un nuevo proyecto, que en mi caso llamaré ComposicionEjemplo.
Como en el ejemplo de construir un automóvil con partes más pequeñas, nuestro ejemplo se basará en una clase sobre un automóvil y otra con sus características, las cuales serán, por un asunto de simplicidad y no complicar el ejemplo, simplemente su marca, modelo y color.

La primera clase que escribiremos se llamará Caracteristica y la guardaremos como archivo de encabezado, con el nombre de Caracteristica.h
Esta clase llevará una función imprimir, la cual será constante. Esto es debido a que su trabajo es mostrar un mensaje el cual no tiene sentido se pueda modificar. Por lo general, las funciones imprimir o funciones get, se declaran como constantes.
Para que una función se declare como constante, debe llevar la palabra const, después de los paréntesis.

#ifndef CARACTERISTICA_H
#define CARACTERISTICA_H

#include<iostream>
using std::string;

class Caracteristica{

  public:
    Caracteristica(string);
    void imprimir()const; //funcion constante

  private:
    const string detalle;
};
#endif // CARACTERISTICA

Ahora lo que vamos a hacer es crear el archivo fuente llamado Caracteristica.cpp
En este archivo vamos a iniciar nuestra constante mediante el constructor y le agregaremos una tarea a nuestra función "imprimir". 

Como se puede ver, el constructor utiliza el inicializador de miembros para iniciar nuestra constante. Además, el constructor utiliza un argumento, el cual también es una constante.
La función imprimir, simplemente muestra en pantalla el contenido de la constante que llamamos "detalle"

#include<iostream>
using std::string;
using std::cout;
using std::endl;

#include "Caracteristica.h"

Caracteristica::Caracteristica(const string d):
  detalle(d){}

void Caracteristica::imprimir()const{
  cout << detalle << endl;
}

Nuestro siguiente archivo, es otro archivo de encabezado al cual nombré como Auto.h
En este archivo, se declaró la clase Auto. Esta clase utiliza lo que llamamos composición, ya que utiliza a la clase Caracteristica, como si se tratase de una variable.

El constructor, utiliza como argumento la clase Caracteristica. Este argumento funciona como si fuese un string, debido a recibirá un texto. Caractaristica, queda como un nuevo tipo de dato el cual utilizamos para declarar las variables marca, modelo y color.

#ifndef AUTO_H
#define AUTO_H

#include<iostream>
using std::string;

#include "Caracteristica.h"

class Auto{

  public:
    Auto(const string, Caracteristica, Caracteristica, Caracteristica);
    void imprimir()const;

  private:
    const string vehiculo;
    Caracteristica marca;
    Caracteristica modelo;
    Caracteristica color;
};

#endif // AUTO_H

El siguiente archivo, es otro código fuente, el cual llamaremos Auto.cpp
En este archivo, vamos iniciaremos las variables o constantes, mediante el uso del constructor y utilizaremos la función imprimir, para mostrar un texto por pantalla.

Como se puede ver, el constructor inicia las variables o constantes correspondientes, esta vez utilizando la composición, el cual indica que recibirá cuatro argumentos. 

En la función imprimir, utilizamos la composición para llamar a la función imprimir y que muestre por pantalla el texto que será establecido en la función main.

#include "Caracteristica.h"
#include "Auto.h"

#include<iostream>
using std::string;
using std::cout;
using std::endl;

Auto::Auto(const string v, Caracteristica mar, Caracteristica mod, Caracteristica col):
  vehiculo(v), marca(mar), modelo(mod), color(col){}

void Auto::imprimir()const{
  cout << "Tipo de vehiculo: " << vehiculo << endl;
  cout << "Marca: ";
  marca.imprimir();
  cout << "Modelo: ";
  modelo.imprimir();
  cout << "Color: ";
  color.imprimir();
  cout << endl;
}
 
Por último, creamos el archivo main.cpp
En este archivo creamos tres objetos de la clase Caracteristica; un objeto marca, otro objeto modelo y un objeto color. Estos objetos reciben un argumento de texto. 

Luego creamos un objeto vehículo, de la clase Auto. Este recibe cuatro argumentos, según declaramos en su prototipo. 

Ya por último utilizamos el objeto vehículo para llamar a la función imprimir y mostrar por pantalla los datos ingresados.

#include "Auto.h"

int main(){

  Caracteristica marca("Toyota");
  Caracteristica modelo("Yaris");
  Caracteristica color("Rojo");
  Auto vehiculo("Auto", marca, modelo, color);

  vehiculo.imprimir();

return 0;
}

El resultado es el siguiente:



En una clase anterior, cuando presentamos la envoltura del preprocesador, mencioné que al no incluirlas cuando trabajamos con la composición, podría ocasionar un error al momento de querer compilar. Esto sucede si por ejemplo, borramos la envoltura del preprocesador del archivo Caracteristica.h

Por ejemplo, en la siguiente imagen, al comentar dichas líneas, me arroja un error al querer compilar.
 




Hay que tener presente que esto de la composición, está muy ligado a la herencia y sirve para tener cada clase por separado y enfocada en realizar una tarea.

Espero se haya entendido. Saludos

Gustavo J. Cerda Nilo. Julio 2018

No hay comentarios:

Publicar un comentario

C++ El apuntador This

El apuntador This En C++, cada objeto tiene acceso a su propia dirección a través de un puntero o apuntador denominado This. Lo...