Cerca nel sito:
ricerca
avanzata

Frasi Celebri...

L'aritmetica ha un grande potere nell'elevare la mente costringendola a ragionare intorno a numeri astratti.

Platone 

Sondaggio:

Qual'? il migliore tra i pi? recenti allenatori della nazionale?

Trapattoni
Zoff
Sacchi
Vicini
Maldini

visualizza risultati


 

Membri static

Normalmente istanze diverse della stessa classe non condividono direttamente risorse di memoria, l'unica possibilita` sarebbe quella di avere puntatori che puntano allo stesso indirizzo, per il resto ogni nuova istanza riceve nuova memoria per ogni attributo. Tuttavia in alcuni casi e` desiderabile che alcuni attributi fossero comuni a tutte le istanze; per utilizzare un termine tecnico, si vuole realizzare una comunicazione ad ambiente condiviso. Si pensi ad esempio ad un contatore che indichi il numero di istanze di una certa classe in un certo istante...
Per rendere un attributo comune a tutte le istanze occorre dichiararlo static:

 

class MyClass {
  public:
    MyClass();
    /* ... */

  private:
    static int Counter;
    char * String;
    /* ... */
};

 

Gli attributi static possono in pratica essere visti come elementi propri della classe, non dell'istanza. In questo senso non e` possibile inizializzare un attributo static tramite la lista di inizializzazione del costruttore, tutti i metodi (costruttore compreso) possono accedere sia in scrittura che in lettura all'attributo, ma non si puo` inizializzarlo tramite un costruttore:

 

MyClass::MyClass() : Counter(0) { // Errore!
  /* ... */
}

 

Il motivo e` abbastanza ovvio, qualunque operazione sul membro static nel corpo del costruttore verrebbe eseguita ogni volta che si istanzia la classe, una inizializzazione eseguita tramite costruttore verrebbe quindi ripetuta piu` volte rendendo inutili i membri statici.
L'inizializzazione di un attributo static va eseguita successivamente alla sua dichiarazione ed al di fuori della dichiarazione di classe:

 

class MyClass {
  public:
    MyClass();
    /* ... */

  private:
    static int Counter;
    char * String;
    /* ... */
};

int MyClass::Counter = 0;

 

Successivamente l'accesso a un attributo static avviene come se fosse un normale attributo, in particolare l'idea guida dell'esempio era quella di contare le istanze di classe MyClass esistenti in un certo momento; i costruttori e il distruttore sarebbero stati quindi piu` o meno cosi`:

 

MyClass::MyClass() :  /* inizializzazione membri */
                      /* non static */

{
  ++Counter;          // Ok, non e` una inizializzazione
  /* ... */
}

MyClass::~MyClass() {
  --Counter;          // Ok!
  /* ... */
}

 

Oltre ad attributi static e` possibile avere anche metodi static; la keyword static in questo caso vincola il metodo ad accedere solo agli attributi statici della classe, un accesso ad un attributo non static costituisce un errore:

 

class MyClass {
  public:
    static int GetCounterValue();
    /* ... */

  private:
    static int Counter = 0;
    /* ... */
};

int MyClass::GetCounterValue() {
  return Counter;
}

 

Si noti che nella definizione della funzione membro statica la keyword static non e` stata ripetuta, essa e` necessaria solo nella dichiarazione (anche in caso di definizione inline). Ci si puo` chiedere quale motivo ci possa essere per dichiarare un metodo static, ci sono essenzialmente tre giustificazioni:

  • maggiore controllo su possibili fonti di errore: dichiarando un metodo static, chiediamo al compilatore di accertarsi che il metodo non acceda ad altre categorie di attributi;
  • minor overhead di chiamata: i metodi non static per sapere a quale oggetto devono riferire, ricevono dal compilatore un puntatore all'istanza di classe per la quale il metodo e` stato chiamato; i metodi static per loro natura non hanno bisogno di tale parametro e quindi non richiedono tale overhead;
  • i metodi static oltre a poter essere chiamati come un normale metodo, associandoli ad un oggetto (con la notazione del punto), possono essere chiamati come una normale funzione senza necessita` di associarli ad una particolrare istanza, ricorrendo al risolutore di scope come nel seguente esempio:

MyClass Obj;
int Var1 = Obj.GetCounterValue();       // Ok!
int Var2 = MyClass::GetCounterValue();  // Ok!

 

Non e` possibile dichiarare static un costruttore o un distruttore.

 

 

successivo
–«  INDICE  »–

 

 

 

 
Powered by paper&pencil (carta&matita ) - Copyright © 2001-2022 Cataldo Sasso