© 2023 – 2026, Pau Fernández

PRO2

PRO2

Avaluació
Professorat
Pràctica
•

Lab 1: Classes

•

La classe Data

•

Mètodes

•

Compilació

•

Compilació manual

•

Compilació amb Makefile

•

Classes

•

La classe Racional

Lab 1: Classes

Aquesta sessió es fa sense Jutge! El treball és personal i es pot fer localment en el teu ordinador.

La classe Data

Primer, descarrega el fitxer data.cc

data.cc

La implementació inicial de la qual partim és amb tuples.

  1. Llegeix el programa per veure la seva estructura (quines tuples i funcions té), compila'l i executa'l per confirmar el que has llegit.

  2. Esborra el programa principal, que ara mateix només té una crida a demo_data, i escriu un altre programa fent servir les funcions donades. Es tracta de llegir una seqüència de parelles d'una data d i un enter n, i per a cadascuna mostrar la data d sumant-li n dies. El problema no està perfectament especificat expressament, pren les decisions que consideris oportunes sobre entrada i sortida. Fes també un fitxer de joc de proves per fer la comprovació que el programa funciona correctament (el necessitaràs més endavant!)

Mètodes

  1. Ara converteix totes les funcions que són una operació sobre una Data en mètodes de la tupla Data. Fes tots els canvis necessaris perquè el programa segueixi funcionant de la mateixa manera (comprova-ho amb el teu joc de proves!). Consulta els apunts per recordar els detalls de com han de ser la declaració i les capçaleres de les funcions.

Compilació

  1. El següent pas és dividir el fitxer data.cc en 3 nous fitxers: data.hh, data.cc i main.cc. Consulta els apunts per recordar com fer-ho.

Ara, però, com compilem el programa?

Compilació manual

Podem compilar amb una única comanda, a la qual passem els dos fitxers .cc:

g++ -o demo_data data.cc main.cc

En general, si un programa té més d'un fitxer *.cc, es pot compilar amb:

g++ -o programa *.cc

I l'intèrpret de comandes posarà els noms de tots els fitxers .cc pel fet de posar *.cc. El compilador rep més d'un fitxer .cc i ja fa tots els passos per obtenir l'executable, que involucren la compilació separada de cada fitxer (o mòdul) i el fet d'enllaçar les crides entre mòduls.

Compilació amb Makefile

A la llarga, però, compilar a la línia de comandes és feixuc i cal automatitzar-ho.

  1. Crea un fitxer de nom Makefile, al mateix directori que la resta, amb el següent contingut:

    CXX = g++
    CXXFLAGS = -Wall -std=c++17
    
    demo_data: main.o data.o
        $(CXX) -o demo_data main.o data.o
    
    main.o: main.cc data.hh
        $(CXX) $(CXXFLAGS) -c main.cc
    
    data.o: data.cc data.hh
        $(CXX) $(CXXFLAGS) -c data.cc
    
    clean:
        rm -f *.o demo_data
    

Compte amb els espais! La comanda make necessita que el caràcter d'indentació sigui un tabulador, i quan ho copiïs has de canviar els 4 espais que hi ha davant de les comandes de cada regla per tabuladors. La barra d'estat de VSCode et diu si estàs indentant amb espais o tabuladors (busca un Spaces: 4 i clica-hi per canviar-ho).

Aquest fitxer té un format especial que anirem desxifrant poc a poc, però, en essència, inclou les "instruccions per compilar" el nostre programa pas per pas.

  1. Per fer-lo servir, obre un terminal i mou-te al directori del projecte, i fes:

    make
    

Si és el primer cop que ho fas, veuràs a la sortida això:

g++ -Wall -std=c++17 -c main.cc
g++ -Wall -std=c++17 -c data.cc
g++ -o demo_data main.o data.o

Que són les comandes que ha executat make per compilar el programa pas per pas. Primer ha compilat main.cc, donant com a sortida main.o, després ha fet el mateix amb data.cc i finalment ha enllaçat els dos per donar demo_data.

Però, curiosament, si tornes a fer make un altre cop, tot seguit, veuràs que la sortida és diferent:

make: 'demo_data' is up to date.

Això és perquè make només compila aquelles parts del programa que han canviat per estalviar temps. Si modifiques només el fitxer main.cc, que és el programa principal, però no els mètodes de la Data, no cal recompilar-ho tot. D'això s'encarrega make utilitzant les instruccions que hi ha al Makefile.

Un cop fet tot això, torna't a assegurar que el programa segueix funcionant!

  1. Finalment, fes un ls al terminal a la carpeta del projecte i veuràs els dos fitxers main.o i data.o (que són de codi màquina). A més, hi ha el mateix demo_data, que és el programa sencer. Com que tots aquests fitxers es poden regenerar, no cal guardar-los, i de fet si copies el codi en algun lloc o li envies a algú és bona idea esborrar-los.

    Fes make clean i veuràs que el Makefile també té una regla per això i esborra tots els fitxers generats.

Classes

Ara cal "encapsular" la classe Data, és a dir, fer els seus membres de dades privats (dia, mes, i any).

  1. Canvia struct per class i posa les paraules public: i private: per indicar quins membres són privats i quins públics.

  2. Crea constructors per a la Data que siguin útils per al programa principal. Crea'n un altre, també, per inicialitzar la data amb valors per defecte (com ara la data actual de l'ordinador!).

Torna a compilar amb make i revisa que res s'ha fet malbé i el programa encara fa el mateix. (Oi que sembla que hàgim fet molta feina per res?)

  1. Ara és important que, en el programa principal, provoquis un error de compilació accedint a un camp private: per veure quin missatge d'error ens dóna el compilador. Llegeix-lo bé.

    És ben possible que un dia no te n'adonis i accedeixis a un membre privat sense voler, i et sortirà un missatge com el que veus. Cal recordar-lo!

La classe Racional

Ara canviem de programa i utilitzarem el codi de la solució d'un problema del Jutge (Racionals 4),

racional.cc

El motiu de fer aquest exercici és practicar, és a dir, passar pels mateixos conceptes que has passat en el primer exercici una altra vegada repassant-los en un exemple una mica diferent. Malgrat que et sembli repetitiu (perquè per una banda, ho és), és l'única manera de consolidar conceptes.

En particular, hauries de poder fer les següents transformacions molt més ràpidament:

  1. Crear un joc de proves per poder comprovar que el programa segueix funcionant quan el modifiques.
  2. Passar de funcions a mètodes (fes-ho una per una, no totes de cop!).
  3. Partir el programa en diferents fitxers (fixant-te en què va a cada fitxer i en la protecció de doble-#include).
  4. Compilar el programa separat (opcionalment amb un Makefile).
  5. Convertir la tupla en una classe, afegint els constructors que et semblin millor.