Cerca nel sito:
ricerca
avanzata

Frasi Celebri...

Il banco di prova di un'intelligenza superiore ? la capacit? di contenere due idee opposte allo stesso tempo conservando la propria funzionalit

Francis Scott Fitzgerald 

Sondaggio:

In quale citt? vi piacerebbe vivere?

New York
Londra
Roma
Madrid
Parigi
Milano
Tokyo
Berlino
Altro

visualizza risultati


 

I namespace

Il secondo problema che si verifica con la ripartizione di un progetto in piu` file e` legato alla necessita` di utilizzare identificatori globali unici. Quello che spesso accade e` che al progetto lavorino piu` persone ognuna delle quali si occupa di parti diverse che devono poi essere assemblate. Per quanto possa sembrare difficile, spesso accade che persone che lavorano a file diversi utilizzino gli stessi identificatori per indicare funzioni, variabili, costanti...
Pensate a due persone che devono realizzare due moduli ciascuno dei quali prima di essere utilizzato vada inizializzato, sicuramente entrambi inseriranno nei rispettivi moduli una funzione per l'inizializzazione e molto probabilmente la chiameranno InitModule() (o qualcosa di simile). Nel momento in cui i due moduli saranno linkati insieme (e sempre che non siano sorti problemi prima ancora), inevitabilmente il linker segnalera` errore.
Naturalmente basterebbe che una delle due funzioni avesse un nome diverso, ma modificare tale nome richiederebbe la modifica anche dei sorgenti in cui il modulo e` utilizzato. Molto meglio prevenire tale situazione suddividendo lo spazio globale dei nomi in parti piu` piccole (i namespace) e rendere unicamente distinguibili tali parti, a questo punto poco importa se in due namespace distinti un identificatore appare due volte... Ma vediamo un esempio:

 

// File MikeLib.h
namespace MikeLib {
  typedef float PiType;
  PiType Pi = 3.14;
  void Init();
}

// File SamLib.h
namespace SamLib {
  typedef double PiType;
  PiType Pi = 3.141592;
  int Sum(int, int);
  void Init();
  void Close();
}

 

In una situazione di questo tipo non ci sarebbe piu` conflitto tra le definizioni dei due file, perche` per accedere ad esse e` necessario specificare anche l'identificatore del namespace:

 

#include "MikeLib.h"
#include "SamLib.h"

int main(int, char* []) {
  MikeLib::Init();
  SamLib::Init();
  MikeLib::PiType AReal = MikeLib::Pi * 3.7;

  Areal *= Pi;           // Errore!

  SamLib::Close();
}

 

L'operatore :: e` detto risolutore di scope e indica al compilatore dove cercare l'identificatore seguente. In particolare l'istruzione MikeLib::Init(); dice al compilatore che la Init() cui vogliamo riferirci e` quella del namespace MikeLib. Ovviamente perche` non ci siano conflitti e` necessario che i due namespace abbiano nomi diversi, ma e` piu` facile stabilire pochi nomi diversi tra loro, che molti.
Si noti che il tentativo di riferire ad un nome senza specificarne il namespace viene interpretato come un riferimento ad un nome globale esterno ad ogni namespace e nell'esempio precedente genera un errore perche` nello spazio globale non c'e` alcun Pi.
I namespace sono dunque dei contenitori di nomi su cui sono defite delle regole ben precise:

  • Un namespace puo` essere creato solo nello scope globale;

  • Se nello scope globale di un file esistono due namespace con lo stesso nome (ad esempio i due namespace sono definiti in file header diversi, ma inclusi da uno stesso file), essi vengono fusi in uno solo;

  • E` possibile creare un alias di un namespace con la sintassi: namespace < ID1 > = < ID2 >;

  • E` possibile avere namespace anonimi, in questo caso gli identificatori contenuti nel namespace sono visibili al file che contiene il namespace anonimo, ma essi hanno tutti automaticamente linkage interno. I namespace anonimi di file diversi non sono mai fusi insieme.

 

 

successivo
–«  INDICE  »–

 

 

 

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