L2: Uso de clases
Esta práctica tampoco utiliza el Jutge! De nuevo deberás ser tú mismx quien compruebe que todo funciona como debe 😉. Recuerda que lx profesorx te puede ayudar en todo lo que necesites.
Objetivos de esta sesión:
- Documentar-se sobre los métodos de una clase de diversas maneras.
- Usar clases con métodos documentados sin conocer/entender su implementación.
Parte I: La clase string
Usar una clase es como usar una máquina con botones, hace falta un
manual que diga qué botones hay, y qué hace cada uno. El manual de la
clase string
es la
documentación de referencia.
Lo más importante es la lista de métodos (o
"Member Functions").
La clase string
tiene muchos métodos, pero para simplificar, nos podemos quedar con los 3 siguientes:
Método | Documentación |
---|---|
find | Encuentra un trozo de texto en el string |
substr | Devuelve una copia de una parte del string |
replace | Reemplaza una parte del string por otro string |
Ejemplos:
find
:
// int string::find(const char *a_buscar, int desde);
string s = "a bb ccc bb";
int pos1 = s.find("bb", 0); // desde 0: pos1 -> 2
int pos2 = s.find("bb", 5); // desde 5: pos2 -> 9
// string string::substr(int desde, int longitud);
string s = "1234567";
string tros = s.substr(2, 3); // tros -> "345"
// void string::replace(int pos, int num_borra, string inserta);
string s = "bar???ona";
s.replace(3, 3, "cel"); // s -> "barcelona"
Partir un string
en trozos
Una operación común que algunos lenguajes tienen (pero C++ no 😕), es
la siguiente. Dado un string
formado por un texto con separadores,
como "a; b; c; d"
, devolver un vector
con cada uno de los trozos
resultantes de dividir el string
por el separador. Si éste fuese
"; "
, el resultado sería el vector {"a", "b", "c", "d"}
.
Así pues, descarga este programa:
Compílalo y observa cómo está hecho. En particular:
- La función
split
con su documentación (y el hecho de que al colocar el cursor sobre las llamadas a la función, aparece la documentación). - Qué métodos utiliza el código para poder realizar las operaciones.
- El
operator<<
, que permite imprimir vectores. (Úsalo en tus propios programas.) Es untemplate
para permitir que se pueda aplicar en vectores de cualquier tipo. - Los resultados que se devuelven para cada caso (sobretodo con el separador vacío).
Ejercicio 1: Un dictador llamado Trumpf ha decidido que para que haya auténtica libertad de expresión, se deben prohibir todas las ocurrencias de la palabra "trumpet" de todos los textos del mundo. Es evidente que semejante palabreja es ofensiva e intolerable en el mundo actual. Documéntate sobre el método
replace
(mira la versión 8, hay demasiadas 😅) y la accióngetline
y hazle un programa a Trumpf que lea cada línea de la entrada y reemplace "trumpet" por "[redacted]". Haz la versión más simple de detectar cualquier ocurrencia como palabra o subpalabra, al principio o al final.¿Sin el Jutge, cómo vas a saber cuándo el programa funciona correctamente?
Ejercicio 2: Haz la función complementaria a
split
, llamadajoin
, que recibe unvector<string>
y concatena losstrings
(los trozos) con un separador entre cada pareja de trozos y devuelve elstring
resultante. Piensa qué parámetros tiene, qué pre-condiciones tienen, y escríbela con documentación Doxygen, tomando asplit
como modelo.
Parte II: Fecha
reloaded
La práctica anterior trataba sobre un grupo de
funciones para trabajar con fechas. En esta sesión trabajaremos con la
clase Fecha
.
Descarga el .tar
y descomprímelo en un directorio (el mismo tar
creará un directorio fecha
):
Sitúate en el directorio descomprimido con un terminal y haz:
make
Deberías ver una salida como
g++ -c main.cc
g++ -c fecha.cc
g++ -o demo_fechas main.o fecha.o
Ejecuta el programa demo_fechas
para ver qué hace y luego
familiarízate con el programa principal (main.cc
). Para poder ver
qué hace un método, coloca el cursor del ratón encima de cada método y
lee la documentación que aparece:
Ejercicio 3: Usa la clase
Fecha
para hacer un programa que lee una secuencia de fechas de la entrada y las muestra por orden después. Usa la ordenación que sea menos esfuerzo pero piensa en qué opciones tienes dados los métodos deFecha
.
Ejercicio 4: Haz una función
dias_diferencia
que recibe dosFecha
s y devuelve el número de días que las separan (piensa qué ocurre si te las pasan en el orden inverso a cómo las esperas y qué se le puede hacer). El ejercicio debe hacerse sin cambiar la claseFecha
en absoluto, y solamente usando los métodos disponibles, incluso si tu implementación te parece muy ineficiente.
Si recuerdas, la representación de la Fecha
utiliza los campos
dia
, mes
, y anyo
. Con esta representación, se podría hacer un
algoritmo mucho más eficiente, si dispusiéramos de métodos públicos
como dias_mes
o es_bisiesto
que no se han hecho públicos en
fecha.hh
. Aún así, sería complejo gestionar toda la casuística del
algoritmo para asegurar que sea correcto.
Ejercicio 5: Investiga sobre el "epoch" y la forma de almacenar el tiempo en Unix y reflexiona sobre el problema anterior nuevamente. De las siguientes operaciones, indica cuáles son eficientes y cuáles no:
Operación Dia+Mes+Anyo Epoch Mostrar la fecha como DD/MM/AAAA
Sumar una cantidad de días Diferencia entre días Comparar dos fechas Determinar si una fecha es menor
Parte III: Ventanas!
Las dos secciones siguientes usan una clase Window
que permite abrir
una ventana pintar en ella y detectar teclas y clicks del ratón. La
clase dispone de los siguientes métodos:
-
Window::Window(titulo, ancho, alto, zoom)
: Constructor, abre una ventana con untitulo
, deancho
alto
píxeles, y con una amplificación dezoom
(cada pixel deWindow
es dezoom
zoom
píxeles reales). -
bool Window::next_frame()
: Procesa eventos, refresca la ventana y espera hasta el siguiente fotograma. Devuelvefalse
si el usuario ha cerrado la ventana. -
void Window::clear(color)
: Pinta toda la ventana con uncolor
(por defecto, el negro). -
void Window::set_pixel(pt, color)
: Pinta un solo pixel con un color(pt
es una tupla con dos camposx
ey
). -
bool Window::is_key_pressed(key)
: Devuelvetrue
si una tecla está presionada. -
bool Window::is_mouse_pressed()
: Devuelvetrue
si el botón izquierdo del ratón está presionado. -
Pt Window::mouse_pos()
: Devuelve la posición del ratón (una tupla conx
ey
). -
void Window::sleep(ms)
: Pausa el programams
milisegundos. -
int Window::frame_count()
: Devuelve el número de fotogramas transcurridos hasta el momento.
La documentación de los métodos está en formato Doxygen en
window.hh
, así que para los detalles, consultad la documentación que
aparece en VSCode al ir utilizando los métodos.
Stop Motion
Descarga el .tgz
y descomprímelo. Compila y ejecuta para ver qué
hace el programa. El código demuestra cómo hacer bastantes cosas,
revisa que las entiendes y consulta con el profesor todo aquello que
no veas claro.
Ejercicio 6: Busca en el código el sitio donde se decide el tamaño de la ventana y cambia tanto la anchura como la altura y prueba cómo afecta al programa. Cambia también el "zoom" y observa qué ocurre.
Ejercicio 7: Explica porqué hay un
if
en las dos funcionesprogress_bar_up
ypixel_down
como este:
if (!window.next_frame()) { return false; }
Ejercicio 8: ¿Qué ocurrirá si quitamos la instrucción
window.clear()
de la línea 29? Piénsalo antes sin probarlo! 😉.
Animación
Como de costumbre, descarga, compila y ejecuta el ejemplo. En este caso, la ventana muestra una línea que sube y baja y si clicas con el ratón, muestra una línea amarilla allí donde cliques. Pregunta al profesor lo que no entiendas del código.
Ejercicio 9: Haz que la línea roja solo se muestre si estás apretando la barra espaciadora.
Ejercicio 10: Haz que la línea amarilla se muestre siempre que el ratón esté encima de la ventana, no solo si clicas.
Ejercicio 11: Cambia las dos barras, roja y amarilla, para que sean barras verticales, en vez de horizontales, manteniendo la misma funcionalidad del programa.
Mario

Descarga, compila... ya sabes, lo de siempre.
Ejercicio 12: Haz que Mario se pueda controlar con el teclado, de forma que al presionar las teclas de flechas arriba, abajo, derecha e izquierda, el personaje se mueva en la dirección apropiada. Ignora los límites de la ventana, por ahora.
Ejercicio 13: Haz que Mario choque al llegar a los límites de la ventana y no pueda traspasarlos.
Parte IV: Impresora a Color
Descarga el .tar
siguiente y descomprímelo en una carpeta:
La clase ColorPrinter
sirve para mostrar mensajes en color en el
terminal. Los terminales de Linux son emuladores de terminales físicos
anteriores que tenían
formas de mostrar colores
y cambios en la fuente.
Compila demo_color_printer
usando el Makefile
y comprueba lo que
hace. Documéntate sobre lo que hace la clase y como se utiliza mirando
la documentación y leyendo el programa principal.
Ejercicio 14: Muestra una bandera multicolor hecha de asteriscos en el terminal.
Ejercicio 15: Cambia el ejercicio del señor Trumpf para que la palabra
[redacted]
salga en rojo, y facilite el hecho de encontrar las ocurrencias eliminadas.