using -Deklarationen und using -Direktiven in C++
using -Deklaration
Wenn ein lokaler Name ausschließlich in der Bedeutung aus einem bestimmten Namensraum verwendet werden soll, dann kann er durch eine using -Deklaration „importiert“ werden. Schreibt man das Schlüsselwort "using" gefolgt von dem qualifizieren Namen und einem Semikolon ";", so kann danach der unqualifizierte Name anstelle des qualifizierten Namens verwendet werden.
Das Beispiel des folgenden Programmes zeigt dies für den Namen »cout«, der nach der using -Deklaration »using ::std::cout;« anstelle des explizierten Namens »::std::cout« verwendet werden kann.
main.cpp
#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string> // "susing namespace ::std::literals;
using ::std::cout;
int main(){ cout << 65 << "\n"s; }
::std::cout
65
using -Direktive
Es wäre bei einem größeren Programm aufwendig, die zuletzt beschriebene Deklaration für alle zu verwendenden qualifizierten Namen hinzuschreiben. Statt dessen ist es auch möglich, alle Namen eines Namensraumes für die unqualifizierte Verwendung freizugeben.
Hierzu wird eine using-Direktive verwendet, bei der nach »using namespace « der Name eines Namensraumes angegeben wird und dann ein Semikolon folgt. Dadurch werden alle lokalen Namen des Namensraumes zur unqualifizierten Benutzung freigegeben.
main.cpp
#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string> // "susing namespace ::std::literals;
using namespace ::std;
int main(){ cout << 65 << "\n"s; }
::std::cout
65
Nachteile von using -Direktiven
Durch die using-Direktive wird die Trennung in Namensräume aufgehoben und der Nutzen von Namensräumen wird somit sabotiert.
Dies kann zu Problemen führen, wenn ein Programmierer in seinem Programm selber einen Namen definiert, der schon in einem der Namensräume vorkommt, welche mit der using-Direktive importiert wurden. Da dies viele Namen sind, wird ein Programmierer sich ihrer vermutlich nicht immer bewußt sein.
Bei der Verwendung mehrerer using -Direktive ist es auch weniger klar, zu welchem Namensraum ein im Programm verwendeter Name nun gehört.
Es kann auch sein, daß die Verwendung mehrerer using -Direktiven zunächst nicht zu Problemen führt, aber später Probleme auftreten werden, weil die importierten Namensräume im Laufe der Zeit erweitert wurden.
Deswegen wird die Verwendung der using -Direktive von einigen erfahrenen Programmierern oft abgelehnt, es gibt aber auch andere, die sie regelmäßig verwenden.
Die using -Direktive kann eventuell einmal nützlich sein, wenn ältere Programme aus der Zeit als es in C++ noch keine Namensräume gab, mit einem neueren C++ -Compiler übersetzt werden sollen.
Bei kleinen Programmen für den kurzfristigen Gebrauch, bei denen es nicht darauf ankommt, daß sie langfristig einsetztbar und wartbar sind, ist die Verwendung der using -Direktive ebenfalls akzeptabel.
Using-Deklarationen sollten nach den include-Direktiven, aber vor dem Rest des Programms geschrieben werden.
hallo.cpp
#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string> // "susing namespace ::std::literals;
using ::std::cout;
int main(){ cout << "Hallo!"s << "\n"s; }
Die Direktive »using namespace ::std::literals;«
Die Direktive »using namespace ::std::literals;« erlaubt es, bestimmte Schreibweisen für Literale, wie »""s«, mit einem »s« am Ende zu schreiben. Ohne diese Direktive, müßte statt »s« »::std::literals::string_literals::s« geschrieben werden, was aber andererseits an dieser Stelle hinter den Anführungszeichen gar nicht erlaubt ist, da dort keine Bereichsauflösungsoperatoren erlaubt sind. Außerdem wäre es wirklich unangemessen lang.
hallo.cpp
#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string> // "susing namespace ::std::literals;
int main(){ ::std::cout << "Hallo!"s << "\n"s; }
Diese Direktive ist daher unvermeidlich, wenn bestimmte Schreibweisen für Literale wie »""s« verwendet werden sollen. Es spricht daher nichts gegen die Verwendung dieser Direktive.
Die Schreibweise ohne »using namespace ::std::literals;« *
Die in diesem Abschnitt nur zur Illustration gezeigten Schreibweisen müssen hier nicht genau verstanden werden!
Ohne »using namespace ::std::literals;« wäre die folgende, kompliziertere Schreibweise in der letzten Zeile nötig.
main.cpp
#include <iostream>
#include <ostream>
#include <string>int main(){ ::std::cout << ::std::literals::operator""s( "Hallo, Welt", 11 )<< '\n'; }
transcript
Hallo, Welt
Nach »using namespace ::std::literals;« kann diese zunächst zur folgenden Schreibweise verkürzt werden.
main.cpp
#include <iostream>
#include <ostream>
#include <string>using namespace ::std::literals;
int main(){ ::std::cout << operator""s( "Hallo, Welt", 11 )<< '\n'; }
transcript
Hallo, Welt
Danach kann »operator""s( "Hallo, Welt", 11 )« dann weiter zu der im Kurs normalerweise verwendeten Schreibweise »"Hallo, Welt"s« verkürzt werden.
Übungsfragen *
- ? Die using -Deklaration
- Welche der Programmausschnitte enthalten eine using -Deklaration?
- o »int main(){ ::std::cout << 65 << "\n"; }«
o »using ::std::cout; int main(){ cout << 65 << "\n"; }«
o »using namespace ::std; int main(){ cout << 65 << "\n"; }«