Die Aussage Verwenden des Namensraums std wird allgemein als schlechte Praxis angesehen. Die Alternative zu dieser Anweisung besteht darin, den Namespace, zu dem der Bezeichner gehört, bei jeder Typdeklaration mit dem Bereichsoperator (::) anzugeben.
Obwohl die Aussage uns das Tippen erspart Standard:: Wann immer wir auf eine im std-Namespace definierte Klasse oder einen Typ zugreifen möchten, wird die Gesamtheit importiert std Namespace in den aktuellen Namespace des Programms. Nehmen wir ein paar Beispiele, um zu verstehen, warum das vielleicht nicht so gut ist
Nehmen wir an, wir möchten den cout aus dem std-Namespace verwenden. Also schreiben wir
Beispiel 1:
CPP
#include> using> namespace> std;> > cout <<>' Something to Display'>;> |
Computer definieren
>
>
Jetzt, in einem späteren Entwicklungsstadium, möchten wir eine andere Version von cout verwenden, die beispielsweise in einer Bibliothek namens foo benutzerdefiniert implementiert ist.
CPP
Base64-Javascript-Dekodierung
#include> #include> using> namespace> std;> > cout <<>' Something to display'>;> |
>
>
Beachten Sie, dass jetzt eine Unklarheit besteht: Auf welche Bibliothek verweist cout? Der Compiler erkennt dies möglicherweise und kompiliert das Programm nicht. Im schlimmsten Fall kann es sein, dass das Programm zwar kompiliert, aber die falsche Funktion aufruft, da wir nie angegeben haben, zu welchem Namespace der Bezeichner gehört.
Namespaces wurden in C++ eingeführt, um Konflikte bei Bezeichnernamen zu lösen. Dadurch wurde sichergestellt, dass zwei Objekte den gleichen Namen haben und dennoch unterschiedlich behandelt werden können, wenn sie zu unterschiedlichen Namensräumen gehören. Beachten Sie, dass in diesem Beispiel genau das Gegenteil eingetreten ist. Anstatt einen Namenskonflikt zu lösen, erzeugen wir tatsächlich einen Namenskonflikt.
Wenn wir einen Namespace importieren, ziehen wir im Wesentlichen alle Typdefinitionen in den aktuellen Bereich. Der Standard-Namespace ist riesig. Es verfügt über Hunderte von vordefinierten Bezeichnern, daher ist es möglich, dass ein Entwickler die Tatsache übersieht, dass es in der Standardbibliothek eine andere Definition seines beabsichtigten Objekts gibt. Da sie sich dessen nicht bewusst sind, spezifizieren sie möglicherweise ihre eigene Implementierung und erwarten, dass diese in späteren Teilen des Programms verwendet wird. Somit gäbe es im aktuellen Namensraum zwei Definitionen für denselben Typ. Dies ist in C++ nicht zulässig, und selbst wenn das Programm kompiliert wird, kann nicht festgestellt werden, welche Definition wo verwendet wird.
Die Lösung des Problems besteht darin, mithilfe des Bereichsoperators (::) explizit anzugeben, zu welchem Namespace unser Bezeichner gehört. Somit kann eine mögliche Lösung für das obige Beispiel sein
CPP
#include> #include> > // Use cout of std library> std::cout <<>'Something to display'>;> > // Use cout of foo library> foo::cout <>'Something to display'>;> |
>
>
Aber ich muss tippen Standard:: Jedes Mal, wenn wir einen Typ definieren, ist es mühsam. Außerdem sieht unser Code bei vielen Typdefinitionen haariger aus und erschwert das Lesen des Codes. Betrachten Sie zum Beispiel den Code zum Abrufen der aktuellen Uhrzeit im Programm
Beispiel 2:
CPP
#include> #include> > auto> start = std::chrono::high_performance_clock::now()> > // Do Something> > auto> stop> >= std::chrono::high_peformance_clock::now();> auto> duration> >= std::duration_cast(stop - start);> |
Javascript onclick
>
>
Der mit komplizierten und langen Typdefinitionen übersäte Quellcode ist nicht sehr einfach zu lesen. Dies möchten Entwickler vermeiden, da ihnen vor allem die Wartbarkeit des Codes am Herzen liegt.
Es gibt mehrere Möglichkeiten, dieses Dilemma zu lösen, z. B. die Angabe eines genauen Namespace, ohne den Code mit Standardschlüsselwörtern zu verunreinigen.
Erwägen Sie die Verwendung von Typedefs
Typedefs ersparen uns das Schreiben langer Typdefinitionen. In unserem Beispiel 1 könnten wir das Problem lösen, indem wir zwei Typedefs verwenden, eine für die Standardbibliothek und eine für foo
CPP
#include> #include> > typedef> std::cout cout_std;> typedef> foo::cout cout_foo;> > cout_std <<>'Something to write'>;> cout_foo <<>'Something to write'>;> |
>
>
Anstatt ganze Namespaces zu importieren, importieren Sie einen verkürzten Namespace
In Beispiel 2 hätten wir nur den Chrono-Namespace unter std importieren können.
CPP
So bestimmen Sie die Monitorgröße
#include> #include> > // Import only the chrono namespace under std> using> std::chrono;> > auto> start = high_performance_clock::now();> > // Do Something> auto> stop = high_performance_clock::now();> auto> duration duration_cast(stop - start);> |
>
>
Wir können die Anweisung auch zum Importieren eines einzelnen Bezeichners verwenden. Zum Importieren könnten wir nur std::cout verwenden
using std::cout;>
Wenn Sie dennoch ganze Namespaces importieren, versuchen Sie, dies innerhalb von Funktionen oder einem begrenzten Bereich und nicht im globalen Bereich zu tun.
Verwenden Sie die std-Anweisung using namespace innerhalb von Funktionsdefinitionen oder Klassen- und Strukturdefinitionen. Dabei werden die Namespace-Definitionen in einen lokalen Bereich importiert und wir wissen zumindest, wo eventuelle Fehler entstehen, wenn sie doch auftreten.
CPP
k nächster Nachbar
#include> > // Avoid this> using> namespace> std;> > void> foo()> {> >// Inside function> >// Use the import statement inside limited scope> >using> namespace> std;> > >// Proceed with function> }> |
>
>
Abschluss.
Wir haben alternative Methoden für den Zugriff auf einen Bezeichner aus einem Namespace besprochen. Vermeiden Sie auf jeden Fall den Import ganzer Namespaces in den Quellcode.
Auch wenn das Erlernen und Entwickeln guter Codierungspraktiken einige Zeit in Anspruch nehmen kann, zahlen sie sich auf lange Sicht im Allgemeinen aus. Das Ziel eines jeden Programmierentwicklers sollte es sein, sauberen, eindeutigen und robusten fehlerfreien Code zu schreiben.