Ejercicio 2
Ejercicio 2: Genericidad (3.5 puntos)
En este ejercicio vas a aplicar el concepto de genericidad en C++ usando plantillas (templates) para transformar una clase concreta en una clase genérica y reutilizable. Se te proporciona una clase que no utiliza plantillas y tendrás que crear una plantilla en base a esa clase.
Descripción general
Se proporciona una clase IntBox
, que representa un contenedor capaz de almacenar un conjunto de enteros (int16_t
) en una estructura de tamaño fijo. Tu objetivo será generalizar el código para poder construir contenedores (Box
) que puedan almacenar cualquier tipo de dato. El contenedor genérico permitirá configurar el tamaño del mismo como un parámetro de plantilla a la hora de declarar las variables de tipo Box, de manera que, al crear un nuevo objeto de tipo Box, se le indicará el tipo de datos que almacenará y cuántos elementos es capaz de almacenar.
Código base proporcionado
Se te proporciona el siguiente código funcional pero no generalizado, implementado en intbox.h
y en intbox.cc
. Estos ficheros se encuentran en la carpeta e2
de los archivos de partida.
intbox.h
#ifndef __INTBOX_H__#define __INTBOX_H__
#include <cstdint>
namespace C3{ class IntBox { public: IntBox(); void add(int16_t value); int16_t get(uint32_t index) const; uint32_t size() const;
private: int16_t data[100]; uint32_t count; };}#endif /*__INTBOX_H__*/
intbox.cc
#include "intbox.h"#include <stdexcept>
namespace C3{ IntBox::IntBox() : count(0) {}
void IntBox::add(int16_t value) { if (count >= 100) throw std::runtime_error("Box is full"); data[count++] = value; }
int16_t IntBox::get(uint32_t index) const { if (index >= count) throw std::out_of_range("Invalid index"); return data[index]; }
uint32_t IntBox::size() const { return count; }}
- Fíjate en el detalle de que, aunque el contenedor de enteros tiene elementos de tipo
int16_t
, también se trabaja conint32_t
, pero este tipo de dato se utiliza para representar una posición dentro del contenedor. Tenlo en cuenta ya que son dos tipos de datos diferentes.
Tarea
Debes crear una clase nueva llamada Box
basándote en IntBox
y utilizando las plantillas de C++ (template) para permitir almacenar elementos de cualquier tipo, no solo enteros. Esta clase nueva se llamará Box<T, N>
, donde:
T
es el tipo de los elementos que contiene el contenedor.N
es la capacidad máxima del contenedor (definida en tiempo de compilación).
Requisitos
- La clase debe llamarse
Box
. - Se debe separar la interfaz (en el archivo
box.h
) y la implementación (enbox.tcc
), como es habitual al trabajar con templates. Ten en cuenta que el fichero de implementación tiene extensión.tcc
, no es.cc
. - Debe ser una clase plantilla con dos parámetros: el tipo
T
y la capacidadN
. - Debes implementar los métodos
add
,get
ysize
, siguiendo la implementación proporcionada en la claseIntBox
. La lógica de las funciones deberá ser exactamente la misma que enIntBox
, incluyendo los casos en los que se lanza una excepción. Fíjate en la implementación del ficherointbox.cc
para implementar tu ficherobox.tcc
. - La clase debe estar definida en el espacio de nombres
C3
, igual que ocurre con la claseIntBox
.
Ejemplo de uso
#include <iostream>#include "box.h"#include "intbox.h"
using namespace C3;using namespace std;
int main(){ //************************************ // Ejemplo de uso de IntBox... //************************************ std::cout << "**** IntBox ****" << std::endl; IntBox values; values.add(10); values.add(5); std::cout << "Tamaño: " << values.size() << std::endl; std::cout << "Elemento 1: " << values.get(1) << std::endl;
std::cout << endl;
//************************************ // Ejemplo de uso de Box genérico... //************************************ std::cout << "**** BOX ****" << std::endl; Box<std::string, 10> words; words.add("hola"); words.add("mundo");
std::cout << "Tamaño: " << words.size() << std::endl; std::cout << "Elemento 1: " << words.get(1) << std::endl;
try { words.get(4); //No existe esta posición, y esta función lanza una excepción con throw. } catch(const std::exception& e) { std::cout << "No existe la posición accedida en la caja" << std::endl; }
return 0;}
La salida de consola de este código debería ser:
**** IntBox ****Tamaño: 2Elemento 1: 5
**** BOX ****Tamaño: 2Elemento 1: mundoNo existe la posición accedida en la caja
- Modifica el fichero
main_e2.cc
tanto como necesites para probar que tu código funciona correctamente.
Entrega
-
Recuerda que puedes crear el archivo comprimido
irp2-c3.tgz
automáticamente si utilizas elMakefile
con la instrucciónmake tgz
. Este archivo contendrá tanto el ejercicio 1 como el ejercicio 2. Tienes más información en el apartado de Instrucciones del examen de prácticas. -
Un error de compilación/enlace implicará un cero en el ejercicio donde se produzca, por tanto asegúrate de que tu código compila correctamente aunque determinadas funciones no hagan nada o no lo hagan bien.
-
Recuerda que al principio de todos los ficheros fuente (`.h’ y `.cc’) entregados y escritos por ti se debe incluir un comentario con tu NIF (o equivalente) y tu nombre, como en el siguiente ejemplo. Ponlo exactamente igual, cambiando los datos personales por los tuyos.
// NIF: 12345678-Z// NOMBRE: GARCIA PEREZ, LAURA -
Lugar y fecha de entrega :
La entregas se realiza siempre en (y sólo en)
https://pracdlsi.dlsi.ua.es en las fechas y condiciones allí publicadas. Puedes entregar los ejercicios tantas veces como quieras, sólo se corregirá la última entrega (las anteriores no se borran). El usuario y contraseña para entregar prácticas es el mismo que se utiliza en UACloud.