3. Costruttori e Distruttori



3.1 Costruttori e Distruttori di una classe

Il Costruttore ed il Distruttore sono funzioni membro che vengono automaticamente chiamate, rispettivamente, quando viene istanziato un oggetto della classe per la prima volta e quando esso cessa di essere usato.
Si è già accennato al fatto che il Costruttore reca lo stesso nome della classe a cui appartiene (in modo che il compilatore possa capire che si tratta di un costruttore) e non restituisce alcun valore.
Una classe, inoltre, può avere più versioni di un costruttore, a seconda dei parametri passati ad esso. Se non esplicitamente indicato, viene sempre chiamato il costruttore senza parametri, detto Costruttore di default .

Il Distruttore è unico e non può avere parametri formali: sintatticamente esso porta lo stesso nome della classe preceduto dal simbolo "~". La sintassi è:
~nomeclasse

Vediamo un esempio di costruttori multipli e distruttore:

class Contatore
{
  int Valore;
  public:
  Contatore();	   //Costruttore di default
  Contatore(int);  //Altro costruttore
  ~Contatore();	   //Distruttore
  . . . . . . .
}

Contatore::Contatore()
{
  valore = 0;
  cout << "Valore iniziale del Contatore: "<< Valore <<"\n";
}

Contatore::Contatore(int v)
{
  valore = v;
  cout << "Valore iniziale del Contatore: "<< Valore <<"\n";
}

int main()
{
  Contatore Counter1;	//Viene chiamato il costruttore di default
  Contatore Counter2(15);  //Viene chiamato l'altro costruttore
}
Quando il programma viene avviato, creando Counter1, verrà automaticamente richiamato il costruttore di default, per cui non è più necessario inizializzare esplicitamente il contatore all'inizio del programma (come sarebbe stato necessario in un programma C).
Al termine del programma viene richiamato automaticamente il distruttore, che libera la memoria associata all'oggetto a cui è riferito.

3.2 Il puntatore "this"

Le funzioni membro di una classe possono riferirsi all'oggetto al quale sono applicate, attraverso il puntatore implicito this. Esso può essere usato solo all'interno di funzioni membro.
Nel corso dei capitoli successivi si comprenderà meglio l'utilità di questo puntatore.


3.3 Superare la protezione: le funzioni "friend"

Il sistema di incapsulamento dei dati realizzato mediante la creazione di un'area "private" all'interno della classe impedisce l'accesso ai dati membro privati da parte di funzioni diverse dalle funzioni membro della classe.
In alcuni casi, però, una classe potrebbe voler permettere a funzioni non membro di accedere ai propri dati membro privati. A tale scopo si usa la parola chiave friend.
Una funzione è friend di una classe quando può accedere ai suoi dati membro privati: tale funzione può essere globale o essere una funzione membro di un'altra classe.
Affinchè il compilatore riconosca una funzione friend, occorre dichiarare il prototipo di tale funzione nella dichiarazione della classe, premettendo a tale prototipo la parola chiave friend.

Vediamo un esempio:

class Contatore
{
  friend void ModificaVal(int Num);
  int Valore;
  public:
  Contatore();
  ~Contatore();
  void Incrementa();
  void Decrementa();
}

Contatore::Contatore()
{
  Valore = 0;
  cout << "Valore iniziale del contatore: " << Valore << "\n";
}

Contatore::void Incrementa()
{
  Valore++;
}

Contatore::void Decrementa()
{
  Valore--;
}

void ModificaVal(int Num)
{
  Valore = Num;
}
Qualora tutte le funzioni membro di una classe X sono friend di un'altra classe Y, si dice che X è una classe friend di Y, e sinteticamente si scrive:
friend class X;
Si noti che questo meccanismo, superando la protezione fornita dalla classe, è potenzialmente pericoloso, in quanto consente libero accesso ai dati interni di una classe, violando le regole di occultamento delle informazioni.

dx
Precedente
back
Home page
dx
Successivo