Skip to content

Namespace

Immagina che due studenti nella stessa classe si chiamino entrambi “Marco”. Ogni volta che la prof dice “Marco!”, nasce confusione. La soluzione? Usare il cognome: “Marco Rossi” e “Marco Bianchi”.

I namespace in C++ funzionano allo stesso modo. Se due librerie diverse definiscono una funzione chiamata print, il compilatore non saprebbe quale usare. Con i namespace, puoi distinguerle: LibreriaA::print e LibreriaB::print.

Tutto quello che fa parte della libreria standard del C++ si trova nel namespace std (abbreviazione di “standard”). Per usare cout, devi indicare che appartiene a std:

std::cout << "Ciao!" << std::endl;
std::string nome = "Alice";

Il :: si legge “appartenente a”. Quindi std::cout significa “cout appartenente a std”.

Scrivere std:: ogni volta è scomodo. Con using namespace std; importi tutto il namespace std e puoi usarlo senza prefisso:

#include <iostream>
using namespace std;
int main() {
cout << "Ciao!" << endl; // invece di std::cout e std::endl
string nome = "Alice"; // invece di std::string
return 0;
}

Questa è la forma che hai visto in quasi tutto il codice di questo manuale.

Puoi importare solo i nomi che ti servono, invece di tutto il namespace:

#include <iostream>
using std::cout;
using std::endl;
using std::string;
int main() {
cout << "Ciao!" << endl; // OK — importato
// cin >> x; // ERRORE — cin non è stato importato
return 0;
}

Questo è più preciso ed è la scelta preferita nei progetti grandi.

Puoi usare i namespace per organizzare il tuo codice ed evitare conflitti tra funzioni con lo stesso nome:

namespace Matematica {
const double PI = 3.14159265358979;
double area(double raggio) {
return PI * raggio * raggio; // area del cerchio
}
double perimetro(double raggio) {
return 2 * PI * raggio;
}
}
namespace Geometria {
double area(double base, double altezza) {
return base * altezza; // area del rettangolo
}
}
int main() {
// Nessun conflitto — il compilatore sa qual è quale
cout << Matematica::area(5.0) << endl; // area del cerchio
cout << Geometria::area(4.0, 6.0) << endl; // area del rettangolo
cout << Matematica::PI << endl;
return 0;
}

Puoi mettere namespace dentro altri namespace, come cartelle dentro cartelle:

namespace Scuola {
namespace Matematica {
double calcolaMedia(double a, double b) {
return (a + b) / 2;
}
}
namespace Italiano {
string maiuscolo(string s) {
return s; // semplificato
}
}
}
int main() {
cout << Scuola::Matematica::calcolaMedia(8, 9) << endl; // 8.5
return 0;
}

In C++17 puoi scrivere i namespace annidati in modo più compatto:

namespace Scuola::Matematica {
double calcolaMedia(double a, double b) {
return (a + b) / 2;
}
}

Se un namespace ha un nome lungo, puoi dargli un soprannome:

namespace MioSistemaGestioneStudenti {
void aggiungiStudente(string nome) { /* ... */ }
}
namespace MSGS = MioSistemaGestioneStudenti; // soprannome
int main() {
MSGS::aggiungiStudente("Alice"); // molto più comodo!
return 0;
}

Non scrivere mai using namespace std; dentro un file header (.h). Chi include il tuo header si ritroverebbe importato tutto std senza saperlo — potrebbe causare conflitti di nomi inaspettati:

// mio_header.h — SBAGLIATO
using namespace std; // "inquina" il namespace di chi include questo file
// mio_header.h — CORRETTO
void funzione(std::string s); // usa il prefisso esplicito
#include <iostream>
#include <cmath>
using namespace std;
namespace Cerchio {
const double PI = 3.14159265358979;
double area(double r) { return PI * r * r; }
double perimetro(double r) { return 2 * PI * r; }
}
namespace Rettangolo {
double area(double b, double a) { return b * a; }
double perimetro(double b, double a) { return 2 * (b + a); }
double diagonale(double b, double a) { return sqrt(b*b + a*a); }
}
int main() {
double r = 5.0;
cout << "Cerchio con raggio " << r << ":" << endl;
cout << " Area: " << Cerchio::area(r) << endl;
cout << " Perimetro: " << Cerchio::perimetro(r) << endl;
double b = 4.0, a = 3.0;
cout << "\nRettangolo " << b << "x" << a << ":" << endl;
cout << " Area: " << Rettangolo::area(b, a) << endl;
cout << " Perimetro: " << Rettangolo::perimetro(b, a) << endl;
cout << " Diagonale: " << Rettangolo::diagonale(b, a) << endl;
return 0;
}