- Come si imposta un programma a oggetti ?
- Quali elementi inserire nella classe che rappresenta l’oggetto?
In questo articolo svilupperemo un programma che simula il funzionamento di un televisore allo scopo di mostrare a piccoli passi quali sono i componenti principali di un programma a oggetti senza l’ereditarietà.
Chi volesse già guardare o copiare il codice per provarlo può scendere alla fine dell’articolo andando qui.
Descrizione funzionalità del programma televisore
Il programma che andremo a sviluppare vuole simulare un televisore che:
- abbia le funzionalità standard principali di un telecomando tipo: accendi, spegni, cambia canale, cambia luminosità
- permetta il “parental Control” tramite il blocco di canali indesiderati
- sia pensato per essere posizionato in una particolare stanza tipo: salotto, cucina, stanza dei bambini; questo allo scopo di aggiungere, magari successivamente, la possibilità di adattare il parental control in base alla stanza dove è collocato (o anche l’elenco dei canali preferiti più adatti a quella stanza o alle ore della giornata in cui sto lì)
Componenti di un programma a oggetti
Se conosciamo le basi della programmazione a oggetti sappiamo che una classe (che è la rappresentazione dell’oggetto) dovrebbe avere al suo interno le seguenti cose:
- variabili o attributi che possono essere:
- statici:
- e cioè quelli che rappresentano le caratteristiche dell’oggetto che non cambiano nel tempo; nel nostro esempio:
... private: string marca; int nPollici;//numero di pollici ...
- dinamici dette anche variabili di stato:
- e cioè quelli che rappresentano le variazioni dello stato interno dell’oggetto; nel nostro esempio:
... private: bool accesa;//true: la televisione è accesa, false spenta int volume; int luminosita; int canaleAttuale; string stanza; bool parentalControlAttivo;//true attivo, false: non attivo int canaliBloccati[MAXCANALIBLOCCABILI]; int numCanaliBloccati; ...
-
i metodi che possono essere
- metodi costruttori:
- che sono quelli che vengono chiamati in automatico all’atto dell’istanziazione (ovvero della creazione) dell’oggetto; abbiamo fatto solo tre che riteniamo necessari, ma se ne potrebbero fare altri.
... public: //costruttori televisione(); televisione(string room); televisione(string room, int pollici); televisione(string room, string m, int pollici); ...
- il metodo distruttore
- che viene chiamato in automatico quando l’oggetto cessa di esistere (nel nostro caso il distruttore non farà nulla)
... //distruttore ~televisione(); ...
- tutti gli altri metodi che:
-
- rappresentano azioni, invio o ricezione di messaggi (nel nostro esempio accendi, spegni e altro
... //azioni del telecomando void accendi(); void spegni(); //controlli e visualizzazioni void addBloccoCanale(int c); ...
- oppure servono a settare (setter) o leggere i valori (getter) degli attributi (nel nostro caso, ad esempio: setCanale che serve a impostare il canale premendo sul telecomando)
... //azioni del telecomando void setCanale(int c);//i canali vanno da 0 a CANALEMAX void setLuminosita(int l); void changeCanale(bool su);//su=true aumenta di uno, false diminuisce void changeLuminosita(bool su);//su=true aumenta di uno, false diminuisce void setParentalControl(bool pc);//true = attiva, false=disattiva //controlli e visualizzazioni bool isAccesa(); void visualizzaStato(); void getCanaliBloccati(); ...
- rappresentano azioni, invio o ricezione di messaggi (nel nostro esempio accendi, spegni e altro
Alla chiusura della classe inseriamo il main composto da un menù di scelta tramite un costrutto “switch-case” inserito poi in un ciclo e, subito dopo il main, le implementazioni dei metodi.
Codice sorgente televisore in C++
Ecco il codice sorgente completo che potete anche provare su Ideone dove sono stati dati i seguenti Input:
11 1 11 3 11 13 (11 visualizza lo stato, 1 accende, 3 cambia canale, 13 esce)
#include <iostream> #include <stdlib.h> #define MAXCANALIBLOCCABILI 50 #define MAXCANALE 889 #define MAXLUMINOSITA 100 using namespace std; class televisione { private: bool accesa; string marca; int nPollici; int volume; int luminosita; int canaleAttuale; string stanza; bool parentalControlAttivo;//true attivo, false: non attivo int canaliBloccati[MAXCANALIBLOCCABILI]; int numCanaliBloccati; bool isBloccato(int c);//dice se il canale c è nell'elenco dei bloccati public: //costruttori televisione(); televisione(string room); televisione(string room, int pollici); televisione(string room, string m, int pollici); //distruttore ~televisione(); //azioni del telecomando void accendi(); void spegni(); void setCanale(int c);//i canali vanno da 0 a CANALEMAX void setLuminosita(int l); void changeCanale(bool su);//su=true aumenta di uno, false diminuisce void changeLuminosita(bool su);//su=true aumenta di uno, false diminuisce void setParentalControl(bool pc);//true = attiva, false=disattiva //controlli e visualizzazioni bool isAccesa(); void visualizzaStato(); void addBloccoCanale(int c); void getCanaliBloccati(); }; //costruttori televisione::televisione() { stanza="salotto"; marca = "LG"; nPollici=22; accesa=false; volume=20; luminosita=50; canaleAttuale=1; parentalControlAttivo=false; for(int i=0; i<MAXCANALIBLOCCABILI;i++) canaliBloccati[i]=0; numCanaliBloccati=0; } televisione::televisione(string room) { stanza=room; nPollici=24; marca = "LG"; accesa=false; volume=20; luminosita=50; canaleAttuale=1; parentalControlAttivo=false; for(int i=0; i<MAXCANALIBLOCCABILI;i++) canaliBloccati[i]=0; numCanaliBloccati=0; } televisione::televisione(string room, int pollici) { stanza=room; nPollici=pollici; marca = "LG"; accesa=false; volume=20; luminosita=50; canaleAttuale=1; parentalControlAttivo=false; for(int i=0; i<MAXCANALIBLOCCABILI;i++) canaliBloccati[i]=0; numCanaliBloccati=0; } televisione::televisione(string room, string m, int pollici) { stanza = room; marca = m; nPollici = pollici; accesa = false; volume = 20; luminosita = 50; canaleAttuale = 1; parentalControlAttivo = false; for(int i=0; i<MAXCANALIBLOCCABILI;i++) canaliBloccati[i]=0; numCanaliBloccati=0; } //implementazione del distruttore televisione::~televisione(){} //implementazione azioni del telecomando void televisione::accendi(){ accesa = true; } void televisione::spegni(){ accesa = false; } void televisione::setCanale(int c) { if( (parentalControlAttivo == true) and (isBloccato(c)) ) return; if((c>=0) and (c<=MAXCANALE)) canaleAttuale = c; //altrimenti il canaleAttuale resta quello di prima } void televisione::setLuminosita(int l) { if((l>=0) and (l<MAXLUMINOSITA)) luminosita = l; } /* void televisione::changeCanale(bool su) { if(su == true) canaleAttuale++; else canaleAttuale--; //qui ho settato il canaleAttuale ma potrebbe essere bloccato if(parentalControlAttivo == true) if(isBloccato(canaleAttuale) ) changeCanale(true); //funzione ricorsiva cioè una funzione che richiama se stessa } */ //versione con controllo errori: void televisione::changeCanale(bool su) { if(su) canaleAttuale = (canaleAttuale+1) % (MAXCANALE+1) ; else canaleAttuale--; if(canaleAttuale == 0 ) if(su) canaleAttuale++; else canaleAttuale = MAXCANALE; //qui ho il canaleAttuale ma potrebbe essere bloccato if(parentalControlAttivo == true) if(isBloccato(canaleAttuale) ) changeCanale(true); //funzione ricorsiva cioè una funzione che richiama se stessa } void televisione::changeLuminosita(bool su) { if(su) luminosita++; else luminosita--; } //versione con controllo degli errori //si fa come quella di changeCanale void televisione::setParentalControl(bool pc) { parentalControlAttivo = true; } //controlli bool televisione::isAccesa(){ return accesa; } void televisione::visualizzaStato() { if( accesa == false ) { cout<<"ATTENZIONE: accendere il televisore"<<endl; return; } cout<<"televisore: "<<marca<<" "<<nPollici<<" pollici"<<endl; cout<<"canale: "<<canaleAttuale<<endl; //eccetera } void televisione::addBloccoCanale(int c) { if(isBloccato(c)) return; if((c>=0) and (c<MAXCANALE)) { canaliBloccati[numCanaliBloccati] = c; numCanaliBloccati++; } return; } bool televisione::isBloccato(int c) { for(int i=0; i<MAXCANALE; i++) if(canaliBloccati[i] == c) return true; return false; } void televisione::getCanaliBloccati() { cout<<"CANALI BLOCCATI: "<<endl; for(int i=0; i<numCanaliBloccati ;i++) cout<<canaliBloccati[i]<<" "; cout<<endl; } int main() { televisione a("bambini"); int scelta; do{ cout<<"scegli:"<<endl; cout<<"0: spegni"<<endl; cout<<"1: accendi"<<endl; cout<<"2: cambia canale"<<endl; cout<<"3: aumenta canale"<<endl; cout<<"4: diminuisci canale"<<endl; cout<<"5: cambia luminosita'"<<endl; cout<<"6: aumenta luminosita'"<<endl; system("pause"); cout<<"7: diminuisci luminosita'"<<endl; cout<<"8: attiva il controllo parentale'"<<endl; cout<<"9: disattiva il controllo parentale'"<<endl; cout<<"10: blocca canale"<<endl; cout<<"11: visualizzaStato"<<endl; cout<<"12: dammi l'elenco dei canali bloccati"<<endl; cout<<"13: esci dal programma"<<endl; cin>>scelta; switch(scelta) { case 0: a.spegni(); break; case 1: a.accendi(); break; case 2: int c; cout<<"dammi il canale: "; cin>>c; a.setCanale(c); break; case 3: a.changeCanale(true); break; case 4: a.changeCanale(false); break; case 5: int l; cout<<"dammi la luminosita: "; cin>>l; a.setLuminosita(l); break; case 6: a.changeLuminosita(true); break; case 7: a.changeLuminosita(false); break; case 8: a.setParentalControl(true); break; case 9: a.setParentalControl(false); break; case 10: cout<<"dammi il canale da bloccare: "; cin>>c; a.addBloccoCanale(c); break; case 11: a.visualizzaStato(); break; case 12: a.getCanaliBloccati(); break; case 13: cout<<"bye bye!!!"<<endl; break; break; default: cout<<"scelta errata!!!"<<endl; system("PAUSE"); } } while(scelta != 13); return 0; }
La versione successiva di questo programma prevederà l’uso dell’ereditarietà.
Per adesso buon divertimento e fatene buon uso ;)!!!