User Tools

Site Tools


appunti3s:namespace

> tornare all'indice degli appunti linguaggio_c

namespace

Generalità

In C++, come in C, si può suddividere il codice sorgente in più file, ed inoltre si possono usare i namespace per organizzare ancora meglio la visibilità degli elementi al loro interno. Di solito, quando più header contengono dichiarazioni di elementi affini o su uno stesso argomento, si possono raggruppare all'interno di uno stesso namespace. Il namespace a cui appartiene un header file viene specificato dentro lo stesso header file.

  • i namespace sono dei contenitori che diminuiscono la visibilità del loro contenuto
  • anche le classi sono un altro modo di definire un namespace
  • i namespace, rispetto alle classi, non contengono funzioni né dati membri
  • i namespace, rispetto alle classi, possono essere estesi anche dopo la loro definizione

Funzioni omonime

In un programma si possono usare due namespace diversi per poter dichiarare due funzioni con lo stesso nome e poterle usare in momenti e contesti diversi.

NOTA: Ogni classe crea automaticamente anche un nuovo namespace

30.h
namespace MioNameSpace 
{
  // tutto ciò che voglio...
}

using

Il namespace viene dichiarato dal programmatore che scrive le funzioni dentro un file.h, ma chi lo usa, lo deve utilizzare all'interno dei file.cpp.

  • la direttiva using in un file.cpp, sottintendere l'uso di un certo namespace per tutte gli elementi utilizzati. Può sembrare comoda ma va usata con moderazione e solo nei file.cpp
    using namespace std;
  • la dichiarazione using è più mirata perché sottintende l'uso di un certo namespace per un solo elemento
     using std::cout; using std::sqrt()

scope resolutor ::

std::string parola;

Nei file.cpp, questo operatore (introduce l'uso di un qualificatore: il namespace) permette di usare un elemento che si trova in un diverso namespace da quello attualmente in uso. Nei file.cpp, in generale, invece che usare la direttiva using è meglio usare lo scope resolutor ::. La direttiva si usa quando è noioso ripetere sempre lo scope resolutor.

Oltre a questo, lo scope resolutor può essere usato anche per definire, nei file.cpp, elementi (cioè funzioni) che erano stati precedentemente solo dichiarate dentro un certo namespace, in un file.h. Questo modo di far è molto importante perché permette, durante la stesura del codice, di separare la parte che riguarda l'interfaccia di una funzione dalla sua implementazione, cioè le dichiarazioni nel file.h dalle definizioni nei file.cpp.

Lo stesso si può ripetere anche per le funzioni membro di una classe, poiché anche le classi definiscono automaticamente un loro namespace.

38.h
//l'interfaccia 
namespace MioNameSpace
{
   void fun(std::string x);
}
38.cpp
//l'implementazione
void MioNameSpace::fun(std::string x)
{
  // codice...
}

In quest'ultimo esempio si può notare che la funzione (fun) e il tipo dek suo parametro (x) possono non appartenere allo stesso namespace…

namespace come contenitori di più header

La situzione più comune è definire lo stesso namespace per tutti gli header file che riguardano lo stesso argomento (esempio, di una stessa libreria di funzioni)

namespace annidati

omissis…

namespace anonimi

Se in un file.h, dichiaro un namespace senza specificare nessun nome, viene creato un namespace anonimo esclusivamente per questo file.h. Diversamente dal solito, un namespace anonimo non può essere “condiviso” da più header. Si possono aggiungere funzioni e classi a questo namespace solo all'interno di un solo file.h. Come si dovrebbe scrivere per fare una cosa paragonabile all'esempio precedente, nel caso di un namespace anonimo?

39.h
//l'interfaccia ANONIMA
namespace
{
   void fun(int x);
}
38.cpp
//ERRORE: l'implementazione ANONIMA non è possibile dall'esterno
void ::fun(int x)
{
  // codice...
}

Lo potrebbe usare un programmatore che scrive l'interfaccia di una libreria che vuole impedire l'implementazione dall'esterno.

 namespace 
{
// codice...
}

namespace genitori anonimi

Oltre al namespace anonimo di un singolo file, esiste anche un namespace genitore anonimo. Dichiarare oggetti all'interno di questo namespace corrisponde ad usare il livello di visibilità “globale”. Gli elementi globali sembrano comodi da usare perché sono sempre visibili e durano per tutta la durata del programma, ma sono di solito uno spreco e una cattiva abitudine…

Tali elementi sono detti anche “statici”, ma per definire oggetti statici dentro una classe vedi static

 
...

> tornare all'indice degli appunti linguaggio_c

appunti3s/namespace.txt · Last modified: 2020/06/08 22:19 by 127.0.0.1