C++-Programmierung: Namensräume
Definieren
[Bearbeiten]Grundlegend
[Bearbeiten]Namensrä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
[Bearbeiten]Namensrä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
[Bearbeiten]Namensrä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
[Bearbeiten]Namensrä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
[Bearbeiten]using-Deklaration
[Bearbeiten]Im 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
[Bearbeiten]Wollen 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;
}