Vai alla Home Page About me Courseware Federica Living Library Federica Federica Podstudio Virtual Campus 3D La Corte in Rete
 
Il Corso Le lezioni del Corso La Cattedra
 
Materiali di approfondimento Risorse Web Il Podcast di questa lezione

Valeria Vittorini » 14.Meccanismi di Incapsulamento in C++ Namespaces


Conflitti tra nomi

In progetti di dimensioni medio-grandi è possibile che ci siano conflitti tra i nomi esportati tra due differenti librerie (eventualmente provenienti da differenti produttori).

Questo fenomeno è noto come “inquinamento dello spazio dei nomi”.

Il C tenta di risolvere questo problema attraverso l’uso di simboli che “accompagnano” gli identificatori. P.es.:
uso del carattere underscore: _identifier.

Il C++ offre una metodologia che risolve sistematicamente il problema: il meccanismo dei namespace.

Namespaces

I Namespaces permettono di raggruppare classi, oggetti, funzioni, variabili definendo in pratica un ambiente di visibilità per identificatori globali e variabili globali.

Sono molto utili allorchè ci può essere il rischio di omonima (in particolare tra variabili globali).

Dichiarare un namespace

A livello di modulo è possibile dichiarare un namespace nel quale vengono poi definiti tutti i simboli del modulo.

studenti

#ifndef __STUDENTI__
#define __STUDENTI__

namespace p1ing {

typedef struct {

int prefisso;
int matricola;
char* Cognome;
char* Nome;

} Studente;

extern Studente Rappresentante;

}

#endif /* __STUDENTI__ */

Dichiarare un namespace

I nomi raggruppati dal namespace hanno visibilità locale al namespace, in questo senso sono “incapsulati” nel namespace e non sono visibili all’esterno, in questo modo si evitano i conflitti nel caso gli stessi nomi si ripetano nell’ambito del programma.

Il nome del namespace (che a sua volta è un identificativo) è invece un nome globale e può essere usato al di fuori del namespace.

“Apertura” di un namespace

Per poter utilizzare i nomi raggruppati da un namespace, che sono quindi locali al namespace, bisogna esplicitamente “aprire” lo spazio dei nomi, specificando il namespace di cui fanno parte.

L’apertura può essere effettuata in due modi:

1) utilizzando l’operatore binario :: (operatore di risoluzione di visibilità) specificando come operandi il namespace e il nome cui si vuole accedere:

namespace::nome

2) utilizzando l’istruzione :

using namespace nome_namespace;

nel caso in cui tutti i nomi del namespace siano utilizzati con frequenza dal programma

Utilizzare un namespace

using namespace nome_namespace; può essere utilizzato sia per aprire namespace standard che namespace definiti dal programmatore

Mostra codice Mostra codice Mostra codice

Standard ISO C++ 1998

Lo standard ISO C++ 1998 ha codificato tutte le librerie standard del C++ all’interno del namespace std.

Per specificare l’inclusione di una libreria standard (ad esempio iostream.h bisogna utilizzare la notazione:

#include<iostream>

avendo tolto il .h

Convenzionalmente, in C++ gli header files i cui nomi terminano con .h non fanno uso dei namespace.

Per includere una libreria del linguaggio C (ad esempio stdlib.h che contiene tra l’altro la funzione system) bisogna utilizzare la notazione:

#include<cstdlib>

avendo quindi aggiunto una c e tolto il .h

Lo standard C++

Using namespace

stile c

Mostra codice

errore

Mostra codice

stile c++ con risolutore di scope

Mostra codice

stile c++ con direttiva using

Mostra codice

Namespace e membri esterni

Un namespace può contenere sia dichiarazioni che definizioni.

In generale però si usa tenere separate le une dalle altre. In particolare per quanto riguarda le funzioni, esse vengono dichiarate nel namespace ma definite fuori di esso.

In questo è necessario utilizzare l’operatore di risoluzione di visibilità (o l’istruzione using namespace) per qualificare i nomi dei membri definiti altrove (membri esterni).

Esempio

Mostra codice

Conflitti

Possono in ogni caso verificarsi conflitti se:

  • si usano librerie o namespace che raggruppano nomi uguali;
  • si usano contemporaneamente due namespace con lo stesso nome e in cui alcuni nomi sono uguali;
  • il primo caso si risolve utilizzando il risolutore di visibilità per risolvere il conflitto;
  • il secondo caso si può trattare definendo degli alias (sinonimi).

Caso 2: esempio


Namespace con lo stesso nome

Nel caso dell’esempio appena visto, di fatto il primo namespace viene ESTESO con il gruppo dei nomi del secondo (rientrano tutti in un unico namespace) anche se si tratta di namespace specificati in header file diversi (NS1.h e NS2.h).

Questa è una regola generale, dovuta al fatto che il nome di un namespace è estendibile.

Ciò consente di suddividere un namespace tra più blocchi e di distribuirlo in maniera differenziata in header file diversi tra moduli clienti diversi, a seconda della parte di interfaccia che è opportuno che vedano.

Namespace sinonimi

Per alleviare il problema che sorge nel caso di utilizzo di namespace con lo stesso nome che raggruppano identificativi uguali si può ricorrere alla definizione di sinonimi.

Ovvi motivi suggeriscono in genere di dare nomi corti ai namespace, ma questo aumenta la probabilità di avere namespace con lo stesso nome.

E’ possibile dare ad un namespace un nome elaborato (e quindi “improbabile”) e poi definire un “sinonimo” corto da usare in ambito ristretto con minore probabilità di conflitto con il nome di altri namespace.

Namespace sinonimi

Mostra codice

Namespace innestati

I namespace devono essere dichiarati in un ambiente globale, cioè non è possibile dichiarare un namespace all’interno di un blocco, ad esempio all’interno di una funzione.

Tuttavia i namespace possono essere innestati.

I materiali di supporto della lezione

Da C++ a UML: cap. 25

  • Contenuti protetti da Creative Commons
  • Feed RSS
  • Condividi su FriendFeed
  • Condividi su Facebook
  • Segnala su Twitter
  • Condividi su LinkedIn
Progetto "Campus Virtuale" dell'Università degli Studi di Napoli Federico II, realizzato con il cofinanziamento dell'Unione europea. Asse V - Società dell'informazione - Obiettivo Operativo 5.1 e-Government ed e-Inclusion

Fatal error: Call to undefined function federicaDebug() in /usr/local/apache/htdocs/html/footer.php on line 93