Namespace
Cos’è un namespace?
Section titled “Cos’è un 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.
Il namespace std
Section titled “Il namespace std”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”.
using namespace std: la scorciatoia
Section titled “using namespace std: la scorciatoia”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.
using per nomi specifici
Section titled “using per nomi specifici”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.
Creare i tuoi namespace
Section titled “Creare i tuoi namespace”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;}Namespace annidati
Section titled “Namespace annidati”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; }}Alias per namespace lunghi
Section titled “Alias per namespace lunghi”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;}Regola importante per gli header
Section titled “Regola importante per gli header”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 — SBAGLIATOusing namespace std; // "inquina" il namespace di chi include questo file
// mio_header.h — CORRETTOvoid funzione(std::string s); // usa il prefisso esplicitoEsempio pratico: calcolo geometrico
Section titled “Esempio pratico: calcolo geometrico”#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;}