Pagina didattica di G. Servizi
Home >> Linguaggio C++ >> vocabolario C++


livello alto

namespace

Con la parola namespace, sinergicamente congiunta con la parola using, il C++ ha introdotto una gestione più flessibile di quello che nell'ANSI C era il cosiddetto ambito di visibilità globale, ossia quell'ambito esterno a ogni funzione nel quale era possibile dichiarare variabili visibili dall'interno di qualunque altro ambito.

Quantunque il concetto di ambito globale resti valido in C++, l'uso di namespace consente di ritagliarne, per così dire, alcune porzioni contrassegnandole con un nome e rendendole indipendenti l'una dall'altra, al punto che in ciascuna di esse sia possibile ridichiarare diversamente delle variabili con lo stesso nome.
A quel punto, l'accesso alle variabili di ugual nome poste in diversi namespaces è consentito attraverso l'operatore di risoluzione di ambito (l'operatore :: ).

Esempio:

#include <iostream>
using namespace std;

char k = 'k';
namespace Int
{int k = 1;}
namespace Double
{double k = 2.0;}

int main(  )
{cout << "ecco il k dichiarato char " << k << endl,
cout << "ecco il k dichiarato int " << Int :: k << endl,
cout << "ecco il k dichiarato double " << Double :: k << endl;}

L'esempio dovrebbe risultare auto-esplicativo...si osservi che sussiste un ambito globale nel quale è stato dichiarato char k.

Argomenti più avanzati



# include <iostream>

namespace A
{
namespace B
{int a;
double b;
}
int a;
double b;
}

int main(  )
{
A :: b = 3.4,
A :: a = 5,
A :: B :: b = 6.1,
A :: B :: a = 8;
using namespace A :: B;
using namespace std;
cout << a << ' ' << b << ' '
<< A :: a << ' ' << A :: b << endl;
}

L'output di questo programma è, come appare ovvio,
8      6.1      5      3.4





#include <iostream>
using namespace std;
namespace Esterno
{
inline namespace Interno
{
template <typename T> class A{  };
}

template <typename T> void funz(T t) {cout << "sono funz primaria: t = " << t << '\n';}
}
/* si supponga che tutto quanto precede, qui
esplicitamente trascritto per chiarezza d'esempio,
si trovi, in realtà, inserito in un
header file INCLUSO dal preprocessore e che un
programmatore fruitore di quel file scriva SOLO
quel che segue:
*/
struct mia {int i; mia(  ) {i = 66;}};
ostream&operator<<(ostream&o, mia m) {return o << m.i;}
namespace Esterno
{
/*
specializzazione della template class A, che
nell'header era definita solo come vuota.
Ciò si fa nel namespace appropriato...
*/
template<> class A<mia> {public: int j; A(){j = 88;}};
/*
due specializzazioni della funzione template funz, di cui,
nell'header, compare solo il modello primario
*/
template<> void funz(A<mia> t) {cout << "sono funz(A<mia>): t = " << t.j << '\n';}
template<> void funz(double t) {cout << "sono funz(double): t = " << t << '\n';}
}

int main(  )
{
Esterno :: A<mia> a;
funz(a);
Esterno :: funz(1.4);
Esterno :: funz("1.4");
mia m;
Esterno :: funz(m);
}

Se non si fosse qualificato il namespace Interno come inline il programma non si sarebbe potuto compilare: provare per credere; si osservi anche che la richiesta di esecuzione di funz con argomento di tipo Esterno :: A<mia> è la sola che può giovarsi di unqualified lookup, o, meglio, di argument dependent lookup, mercé, appunto, il tipo del parametro a che viene trasmesso (cfr.).

Torna in cima alla pagina