I Membri Statici di una Classe/Struttura

I Membri Statici

The members of a class can be declared using the storage class modifier static. Questi dati membri sono condivisi da tutte le istanze di quella classe e sono memorizzati in un unico posto. Dati membri non-statici vengono creati per ciascuna variabile dell' oggetto della classe.

L'incapacità di dichiarare membri statici di una classe avrebbe comportato la necessità di dichiarare questi dati a livello globale del programma. Romperebbe la relazione tra i dati e la loro classe, e non è coerente con il paradigma di base della programmazione orientata agli oggetti - unione dati e metodi per la loro gestione in una classe. Il membro statico consente ai dati della classe che non sono specifici di una particolare istanza di esistere nell'ambito classe.

Poiché un membro della classe statica non dipende dalla particolare istanza, il riferimento è il seguente:

class_name::variable

dove class_name è il nome della classe, e variabile è il nome del membro della classe.

Come vedete, per accedere al membro statico di una classe, viene utilizzato l'operatore di risoluzione del contesto :. Quando si accede ad un membro statico all'interno dei metodi della classe, l'operatore di contesto è opzionale.

Il membro statico di una classe deve essere esplicitamente inizializzato con il valore desiderato. Per questo esso deve essere dichiarato ed inizializzato in ambito globale. La sequenza di inizializzazione dei membri statici corrisponderà alla sequenza della loro dichiarazione in ambito globale.

Ad esempio, abbiamo la classe CParser usata per l'analisi del testo, ed abbiamo bisogno di contare il numero totale di parole e caratteri elaborati. Abbiamo solo bisogno di dichiarare i necessari membri della classe di statici ed inizializzarli a livello globale. Poi tutte le istanze della classe utilizzeranno i contatori comuni di parole e caratteri.

//+--------------------------------------------------------------------------------+
//| Classe "Text analyzer"                                                         |
//+--------------------------------------------------------------------------------+
class CParser
  {
public:
   static int        s_words;
   static int        s_symbols;
 //--- Costruttore e distruttore
                     CParser(void);
                    ~CParser(void){};
  };
...
//--- Inizializzazione dei membri statici della classe Parser a livello globale
int CParser::s_words=0;
int CParser::s_symbols=0;

Un membro statico della classe può essere dichiarato con la parola chiaveconst. Tali costanti statiche devono essere inizializzate a livello globale con la parola chiave const :

//+--------------------------------------------------------------------------------+
//| Classe "Stack" per memorizzare i dati elaborati                                |
//+--------------------------------------------------------------------------------+
class CStack
  {
public:
                     CStack(void);
                    ~CStack(void){};
...
private:
   static const int  s_max_length; // Massima capacità stack
  };
 
//--- Inizializzazione delle costanti statiche della classe CStack
const int CStack::s_max_length=1000;

Puntatore this #

La parola chiave this denota un implicitamente dichiarato puntatore a sé - ad un'istanza specifica della classe, nel contesto del quale viene eseguito il metodo. Esso può essere utilizzato solo in metodi non statici della classe. Il puntatore this è un implicito non-statico membro di qualsiasi classe.

Nelle funzioni statiche è possibile accedere solo a membri/metodi statici di una classe.

Metodi statici

In MQL5 possono essere utilizzate le funzioni membro del tipo static. Il modificatore static deve precedere il tipo di ritorno di una funzione nella dichiarazione all'interno di una classe.

class CStack
  {
public:
 //--- Costruttore e distruttore
                     CStack(void){};
                    ~CStack(void){};
 //--- Massima capacità stack
   static int        Capacity();
private:
   int               m_length;     // Il numero di elementi nello stack
   static const int  s_max_length; // Massima capacità stack
  };
//+--------------------------------------------------------------------------------+
//| Restituisce il numero massimo di elementi da memorizzare nello stack           |
//+--------------------------------------------------------------------------------+
int CStack::Capacity(void)
  {
   return(s_max_length);
  }
//--- Inizializzazione delle costanti statiche della classe CStack
const int CStack::s_max_length=1000;
//+--------------------------------------------------------------------------------+
//| Funzione di avvio del programma Script                                         |
//+--------------------------------------------------------------------------------+
voidOnStart()
  {
//--- dichiara il tipo di variabile CStack
   CStack stack;
//--- chiama il metodo statico dell'oggetto
   Print("CStack.s_max_length=",stack.Capacity());
//--- può anche essere chiamato nel seguente modo, giacchè il metodo è statico e non richiede la presenza dell'oggetto
   Print("CStack.s_max_length=",CStack::Capacity());
  }

Un metodo con il modificatore const viene chiamato costante e non può modificare i membri impliciti della sua classe. Le dichiarazione di funzioni costanti di una classe e parametri costanti, viene denominata controllo di correttezza-const. Attraverso questo controllo si può essere sicuri che il compilatore garantisce la coerenza dei valori degli oggetti e restituisce un errore in fase di compilazione se vi è qualcosa di sbagliato.

Il modificatore const viene inserito dopo l'elenco degli argomenti all'interno di una dichiarazione della classe. La definizione fuori da una classe deve anche includere il modificatore const:

//+--------------------------------------------------------------------------------+
//| Classe "Rettangolo"                                                            |
//+--------------------------------------------------------------------------------+
class CRectangle
  {
private:
   double            m_width;      // Spessore 
   double            m_height;     // Altezza
public:
   //--- Costruttore e distruttore
                     CRectangle(void):m_width(0),m_height(0){};
                     CRectangle(const double w,const double h):m_width(w),m_height(h){};
                    ~CRectangle(void){};
   //--- Calcola l'area
   double            Square(voidconst;
   static double     Square(const double w,const double h);// { return(w*h); }
  };
//+--------------------------------------------------------------------------------+
//| Restituisce l'area dell'oggetto "Rettangolo"                                   |
//+--------------------------------------------------------------------------------+
double CRectangle::Square(voidconst
  {
   return(Square(m_width,m_height));
  }
//+--------------------------------------------------------------------------------+
//| Restituisce il prodotto di due variabili                                       |
//+--------------------------------------------------------------------------------+
static double CRectangle::Square(const double w,const double h)
  {
   return(w*h);
  }
//+--------------------------------------------------------------------------------+
//| Funzione di avvio del programma Script                                         |
//+--------------------------------------------------------------------------------+
voidOnStart()
  {
//--- crea un rettangolo con i lati uguali a 5 e a 6
   CRectangle rect(5,6);
//--- trova l'area del rettangolo utilizzando un metodo costante
   PrintFormat("rect.Square()=%.2f",rect.Square());
//--- trova il prodotto deei numeri con il metodo statico della classe CRectangle
   PrintFormat("CRectangle::Square(2.0,1.5)=%f",CRectangle::Square(2.0,1.5));
  }

Un ulteriore argomento a favore dell'utilizzo del controllo di costanza è il fatto che in questo caso, il compilatore genera un'ottimizzazione speciale, per esempio, inserisce un oggetto costante nella memoria di sola lettura.

Una funzione statica non può essere determinata con il modificatore const, perché questo modificatore assicura la costanza dei membri dell' istanza quando si chiama questa funzione. Ma, come detto sopra, la funzione statica non può accedere a membri non statici della classe.

Vedi anche

Variabili statiche, Variabili, Riferimenti. Modificatore & e Parola Chiave this