GLG Programs fa uso di cookie per migliorare l'esperienza di navigazione degli utenti, ma non per tracciarne un profilo. Proseguendo nella navigazione, si accetta implicitamente l'utilizzo dei cookie.
[OK]Note legaliNon mi importa
Logo GLGPrograms Logo GLGPrograms

Basi di programmazione C++

[Icona della Guida] Introduzione alla programmazione C/C++

Appunti di programmazione C e C++ su GNU/Linux

Indice

Classi

Il C++ è nato per far fronte alle limitazioni di rappresentabilità delle informazioni del C. Abbiamo già incontrato alcuni costrutti particolari che ci consentono di estendere i tipi fondamentali del C costruendone di nuovi, attraverso enumerati, strutture e unioni. Invece, attraverso le classi, che possiamo considerare come un'estensione delle strutture, è possibile costruire e raccogliere non solo i tipi personalizzati costruiti sino ad ora, ma anche le funzioni che operano su di essi, ponendo particolare attenzione a mantenere sempre la consistenza delle informazioni che raccogliamo.

Funzioni membro

Iniziamo con una classe semplicissima del tutto identica alle strutture che abbiamo utilizzato fino a ora, a parte per un paio di parole chiavi:

#include <iostream>
using namespace std;

class Partecipante  /* la parola chiave class indica che si tratta
                       di una classe e non di una semplice struttura */
{
  public:           /* il significato della parola chiave public sarà chiaro tra un momento */
    short id;
    short eta;
    int punti;
};

int main()
{
  Partecipante alice; /* alice è detto istanza o oggetto della classe Partecipante */
  alice.id = 12;
  alice.eta = 16;
  alice.punti = 0;
}

Come si può vedere, ogni funzione che ha accesso all'oggetto alice è libera di modificarne il suo contenuto. Se introduciamo un po' di regole in questa "gara di Partecipanti", questo comportamento diviene indesiderato, scomodo e persino dannoso.

Ad esempio, stabiliamo che a questa gara possono partecipare solo persone maggiorenni. Con la nostra funzione main abbiamo assegnato ad alice 16 anni, e va contro le regole della gara. Per evitare questo, possiamo scrivere una funzione membro, cioè una funzione interna alla classe, che si preoccupa di aggiornare il valore dell'età solo se il partecipante soddisfa i requisiti. Per far questo, tuttavia, dovremo anche nascondere la variabile eta per evitare che la funzione venga semplicemente ignorata da chi usa la nostra classe.

Nell'esempio che segue:

Si noti che l'accesso ad una funzione membro avviene per mezzo dell'operatore . (punto) ed è identico all'acceso a una qualunque variabile della struttura.

#include <iostream>
using namespace std;

class Partecipante
{
  private:
    short eta;
  public:
    short id;
    int punti;
    bool inserisciEta(short n)
    {
      if (n < 18) return false;
      eta = n;
      return true;
    }
};

int main()
{
  Partecipante alice;
  alice.id = 12;
  if (! alice.inserisciEta(16)) cout << "Errore!" << endl;
  alice.punti = 0;
}

Per esercizio, si modifichi il precedente programma rendendolo interattivo, cioè effettuando le opportune letture dell'input da tastiera, finché non sono soddisfatti tutti i requisiti. Si faccia uso di funzioni membro e ci si affidi ad esse per stabilire la correttezza dei dati. Si aggiunga anche che il punteggio di partenza di ciascun partecipante non può essere inferiore a -50 o superiore a 200.

Costruttore

Il costruttore di una classe è una funzione speciale che viene chiamata automaticamente ogni volta che viene costruita e definita un'istanza della classe. Esso è utile per obbligare l'inserimento di valori iniziali o per inizializzarli con un contenuto standard.

La funzione costruttore ha lo stesso nome della classe, e non restituisce nessun valore, nemmeno void.

#include <iostream>
using namespace std;

class Partecipante
{
  public:
    static short num;
    Partecipante(short, int);
    void print(void);

  private:
    short eta;
    short id;
    int punti;
    bool attivo;
};

short Partecipante::num = 0;

Partecipante::Partecipante(short et, int p = 0)
{
  attivo = true;
  if (et < 18) attivo = false;
  else eta = et;

  if (p < -50 || p > 200) attivo = false;
  else punti = p;

  id = num++;
}

void Partecipante::print(void)
{
  cout << id << "\t" << eta << "\t" << punti << "\t" << attivo << endl;
}

int main()
{
  Partecipante alice(21);
  Partecipante barbara(17, 85);
  Partecipante carlo(27, -4);
  alice.print(); barbara.print(); carlo.print();
}

Anche se non viene descritta esplicitamente una funzione costruttore, il compilatore si occupa comunque di compilare un costruttore di default che, semplicemente, alloca lo spazio necessario a contenere le variabili sullo stack.

Distruttore

Contrapposto al costruttore, troviamo il distruttore, funzione che viene chiamata al termine del ciclo di vita dell'oggetto. Il distruttore di default si occupa semplicemente di deallocare la memoria delle variabili membro sullo stack, ma è utile personalizzarlo, ad esempio, quando, facendo uso dell'allocazione dinamica della memoria, si debbano rilasciare delle celle nello heap.

La funzione distruttore non restituisce nessun valore, nemmeno void, e possiede lo stesso nome della classe, preceduto da ˜ (tilde).

Segue un esempio: lo si compili, si verifichi il suo funzionamento e si provi a modificarlo per esercizio. In particolare, si provi a controllare il programma facendo uso dell'analizzatore di memoria valgrind (vedere il capitolo sui puntatori): se non si utilizza un distruttore personalizzato, la memoria allocata dinamicamente non viene liberata.

/* Bozza di una classe Scaffale, per rappresentare uno scaffale a dimensione
finita in cui è possibile memorizzare i codici dei libri */
class Scaffale
{
  private:
    short max;
    short used;
    int* codice;
  public:
    Scaffale(int);
    ~Scaffale(void);
};

Scaffale::Scaffale(int n)
{
  if (n >= 0) max = n;
  else max = 20;
  codice = new int[max];
  used = 0;
}

Scaffale::~Scaffale(void) /* deallocazione del vettore con i codici dei libri */
{
  delete[] codice;
}

int main()
{
  Scaffale a(10);
  return 0;
}
Pagina scritta da Giovan BattistaGiovan Battista

Hai una domanda? Scrivici!
Questa pagina ti è piaciuta? Condividila!
Share on Facebook Share on Google+ Share on linkedin