C++-Programmierung: Namensräume
Definieren
BearbeitenGrundlegend
BearbeitenNamensräume grenzen den Gültigkeitsbereich besser ab. Dies ermöglicht mannigfaltige Konzepte. Im Folgenden wird in Codebeispielen eine Funktion in Namensräumen definiert. In Namensräumen lässt sich aber auch jegliche sonstige, weitere Definition/Deklaration verpacken.
Für den schnellen Einstieg hier ein Beispiel:
void f() { ; } // Funktion auffindbar im globalen Namensraum
namespace MTF
{
void f() // Funktion auffindbar im Namensraum MTF
{
throw std::exception("f - ausgelöst");
};
}
Im Folgenden der Aufruf:
void g()
{
f(); // f() aus globalem Namensraum wird aufgerufen
MTF::f(); // f() aus Namensraum MTF wird aufgerufen
using namespace MTF; // Namensraum MTF wird sichtbar gemacht
f(); // f() aus Namensraum MTF wird in diesem Fall aufgerufen
}
Verschachtelt
BearbeitenNamensräume lassen sich auch beliebig verschachteln.
namespace MTF
{
namespace XYZ
{
void f() // Funktion auffindbar im Namensraum MTF::XYZ
{
throw std::exception("f - ausgelöst");
};
}
}
Bei späterer Verwendung kann dann die Funktion f() aus dem Unternamensraum des Namensraums MTF::XYZ mit MTF::XYZ::f()
verwendet werden. Dies bietet Vorteile um umfangreiche Abschnitte in Bibliotheken oder großen Programmen gegeneinander abzugrenzen und um die gleichen Bezeichner in unterschiedlichen Namensräumen zu verwenden.
Aliasnamen
BearbeitenNamensräume können Aliasnamen erhalten. Sinn macht dies z.B. bei langen Namen:
namespace Die_geheime_Codesammlung_meiner_tollen_Firma
{
void f() // Funktion auffindbar im Namensraum Die_geheime_Codesammlung_meiner_tollen_Firma
{
throw std::exception("f - ausgelöst");
};
}
namespace MTF = Die_geheime_Codesammlung_meiner_tollen_Firma; // Für Alle, die lieber MTF:: schreiben
Wiedereröffnung
BearbeitenNamensräume können an jeder Stelle – außerhalb von Funktions- und Klassendefinitionen – geöffnet und geschlossen werden und somit in beliebig vielen Quelldateien erweitert werden. Das Öffnen und Schließen muss immer einzeln erfolgen, Konstrukte wie namespace MTF::XYZ { const int a = 3; }
um den Namensraum MTF::XYZ zu erweitern sind nicht möglich.
namespace MTF
{
void f() // Funktion auffindbar im Namensraum MTF
{
throw std::exception("f - ausgelöst");
};
}
void Irgendwas::OnX() { .. }; // Etwas anderes dazwischen
namespace MTF
{
const int v = 19;
void g()
{
f(); // Aufruf von f() - natürlich aus Namensraum MTF (in dem wir uns gerade befinden)
};
}
Wiedereröffnung kann, wie hier ersichtlich, genutzt werden, um einen vorhandenen Namensraum zu erweitern und um auf alle Definitionen darin zuzugreifen, ohne eine Bereichsauflösung z.B. MTF::f()
oder using-Deklaration zu verwenden.
Wenn ein Namensraum nicht von Ihnen selber angelegt wurde, ist allerdings große Vorsicht geboten.
Verwenden
Bearbeitenusing-Deklaration
BearbeitenIm Programm aus der ersten Lektion kommen der Name für die Standardausgabe std::cout
und der Name für den Zeilenvorschub std::endl
vor. Beiden sind die Zeichen std::
vorangestellt. Dabei handelt es sich um einen Namensraum (namespace), in diesem Fall den Namensraum std
der C++-Standardbibliothek. Um nicht jedes Mal std::
schreiben zu müssen, können Sie mit Hilfe der using
-Deklaration die Namen bekannt machen. Anschließend kann std::
weggelassen werden:
#include <iostream>
int main()
{
using std::cout; // macht std::cout bekannt
using std::endl; // macht std::endl bekannt
cout << "Hallo!" << endl; // hier kann std:: weggelassen werden
}
Wie eine Variablen-Deklaration gilt using
für den jeweiligen Block.
using-Direktive
BearbeitenWollen Sie nicht nur einzelne Namen, sondern einen ganzen Namensraum bekannt machen, verwenden Sie die Direktive using namespace
:
Da durch den Gebrauch von using namespace
Namensbereiche ihren ursprünglichen Sinn, der Schutz vor Merfachbenennung, verlieren, wird es als besserer Programmierstil angesehen, wenn man die Elemente einzeln mit der using-deklaration
einbindet.
#include <iostream>
#include <string>
int main()
{
using namespace std; // macht alles aus dem Namensraum std bekannt
string text("Peter!");
cout << text << endl;
text = "Hans";
cout << text << endl;
}