Namespace
Cos’è un namespace?
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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
Sezione intitolata “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;}