Come dichiarare una classe

Questa pagina tratta di:
Una classe è davvero una componente software. Quindi un buon modo di implementarla è di mettere la dichiarazione della classe in un file header e il codice isolato in un file C++.

Dichiarazioni di Classi

La dichiarazione di una classe è davvero semplice. La parola chiave class deve essere seguita dal nome delle classe e dalla dichiarazione di variabili e metodi interni alla classe, come mostrato nell'esempio:
class Complex
{
  float r, i;
public:
  float GetRe();
  float GetIm();
  float Modulus();
};

Puoi notare che:

public è una parola chiave che indica che le funzioni GetRe, GetIm e Modulus possono essere chiamate anche al di fuori dell'oggetto. Non c'è alcuna parola chiave prima di r e i, perciò essi sono dichiarati privati per default, e non sono accessibili dall'esterno.

Infatti, ci sono tre tipi di funzioni membro:

Quando dichiari una classe con la parola riservata class, ogni membro è "private" per default. Puoi anche dichiarare una classe con la keyword struct; in tal caso ogni membro sarà "public" per default. Questa è l'unica differenza tra struct e class.
class Complex
{
  float r, i;       // Private per default
};
struct Complex
{
  float r, i;       // Pubbliche per default
};

Implementazione delle funzioni membro

Dopo la dichiarazione della classe, devi implementare le funzioni membro. Basta dire al compilatore di quale classe le funzioni fanno parte, mettendo il nome della classe seguito da :: prima del nome della funzione.

Col nostro esempio precedente:

float Complex::Modulus()
{
  return sqrt(r*r + i*i);           // Notare l'uso di r e i
}
In queste funzioni membro, puoi usare ogni metodo o variabile dell'oggetto come se fosse dichiarato globalmente. L'uso fatto sopra di r ed i dà l'idea.

Instanziazione di una classe come una variabile

Una classe può essere usata come ogni altro tipo di variabile. Per dichiarare un oggetto appartenente alla classe (ndt: o possiamo dire "al tipo della classe"), basta mettere il nome della classe seguito dal nome dell'oggetto che vogliamo creare.

Per esempio, per usare la classe complex possiamo scrivere:

Complex x, y;         // Dichiarazione
Complex vector[10];   // Array di Complex (di numeri complessi)
...
x = y;                // Utilizzo di oggetti dichiarati

Allocazione Dinamica

I puntatori ad oggetti si dichiarano esattamente come in C, con un "*". Si può anche ottenere l'indirizzo di un oggetto con l'operatore "&".
Complex x;          // Dichiarazione di un oggetto Complex
Complex *y;         // Dichiarazione di un puntatore ad (un oggetto) Complex
y = &x;             // y punta ad x
La chiamata C++ corrispondente alla malloc() del C è l'operatore new. Esso alloca spazio in memoria per un oggetto e ritorna un puntatore a questa area appena allocata. Per disallocare l'oggetto e liberare la memoria associata, usa l'operatore delete. Dopo una chiamata a delete lo spazio di memoria è stato restituito allo heap e non va più utilizzato direttamente tramite il puntatore.
Complex *p, *q;      // Dichiarazione di due puntatori
p = new Complex;     // Allocazione dinamica di un singolo Complex
q = new Complex[10]; // Allocazione dinamica di un array di 10 Complex
...                  // Codice che usa p e q
delete p;            // Libera memoria per un singolo oggetto
delete [] q;         // Libera la memoria di un array
Notare l'uso di [] per dire al compilatore che deve essere eliminato un array dinamico. Se non specifichi questo, nella maggior parte dei casi (dipende dal compilatore) sarà liberato solo il primo oggetto dell'array, non l'intera memoria associata. Inoltre anche l'effetto di usare delete [] con un singolo oggetto è indefinito.

Puoi usare gli operatori new e delete ovunque nel codice, proprio come malloc. Non dimenticare di liberare la memoria associata ad un oggetto quando esso non serve più. Vedi la sezione construttori e distruttori per maggiori informazioni.

Usare i membri di un oggetto

Una volta che hai dichiarato un nuovo oggetto, puoi accedere ai suoi membri pubblici come faresti con una struttura in C. Basta usare il separatore . con un oggetto dichiarato staticamente, e -> con uno dichiarato dinamicamente.
Complex x;                    // Oggetto Statico
Complex *y = new Complex;     // Oggetto Dinamico
float a;
a = x.Modulus();               // Chiamata della funzione membro Modulus dell'oggetto Complex
a = y->Modulus();
delete y;
Class foo
{
  int a;            // membro privato
  int Calc();       // funzione privata
public:
  int b;
  int GetA();
};

Auto-riferimento ad un oggetto: this

Finora, siamo stati in grado di usare qualsiasi membro di una classe all'interno di essa, considerandoli come variabili dichiarate. Ma potresti voler ottenere l'indirizzo di un oggetto all'interno di una sua funzione membro, per esempio per inserire un oggetto in una lista concatenata.

La soluzione è la parola riservata this. this è un puntatore del tipo (object *const), e punta all'oggetto corrente. È una variabile membro implicita, dichiarata come private. Esempio:

class A
{
  int a, b;
public:
  void Display();
};

void A::Display()
{
  printf ("Object at [%p]: %d, %d.\n", this, a, b);
}
Notate che il tipo di this è "puntatore costante ad un oggetto object". Questo significa che il valore del puntatore this non puņ essere alterato, mentre l'oggetto puntato ovviamente sì.


C++