3261 Stimmen

Warum wird "using namespace std;" als schlechte Praxis angesehen?

Ich habe von anderen gehört, dass das Schreiben using namespace std; im Code falsch ist, und dass ich Folgendes verwenden sollte std::cout y std::cin stattdessen direkt.

Warum ist using namespace std; eine schlechte Praxis? Ist es ineffizient oder besteht die Gefahr, dass mehrdeutige Variablen deklariert werden (Variablen, die denselben Namen haben wie eine Funktion in std Namespace)? Wirkt sich das auf die Leistung aus?

710 Stimmen

Vergessen Sie nicht, was Sie tun können: "using std::cout;", was bedeutet, dass Sie nicht std::cout eingeben müssen, aber nicht gleichzeitig den gesamten std-Namensraum mit einbeziehen.

115 Stimmen

Es ist besonders schlecht, 'using namespace std' in Headerdateien im Dateisystem zu verwenden. Die Verwendung in Quelldateien (*.cpp) im Dateisystem nach allen Includes ist nicht ganz so schlimm, da ihre Wirkung auf eine einzige Übersetzungseinheit beschränkt ist. Noch weniger problematisch ist die Verwendung innerhalb von Funktionen oder Klassen, da die Wirkung auf den Funktions- oder Klassenbereich beschränkt ist.

15 Stimmen

Ich würde davon abraten, die using-Direktive zu verwenden, aber für bestimmte Namespaces wie std::literals::chrono_literals , Poco::Data:Keywords , Poco::Units und andere Dinge, die mit Literalen oder Lesbarkeitstricks zu tun haben. Immer dann, wenn es in Header- oder Implementierungsdateien steht. In einem Funktionsbereich mag es in Ordnung sein, aber abgesehen von Literalen und anderen Dingen ist es nicht nützlich.

6voto

Noneyo Getit Punkte 77

Um Ihre Frage zu beantworten, betrachte ich es praktisch so: Viele Programmierer (nicht alle) berufen sich auf den Namensraum std. Daher sollte man sich angewöhnen, KEINE Dinge zu verwenden, die den gleichen Namen wie der Namensraum std haben oder verwenden. Das ist zugegebenermaßen viel, aber nicht so viel im Vergleich zu der Anzahl der möglichen zusammenhängenden Wörter und Pseudonyme, die man sich ausdenken kann, um genau zu sein.

Ich meine wirklich ... sagen "verlassen Sie sich nicht darauf, dass dies vorhanden ist" ist nur die Einrichtung Sie verlassen sich auf es NICHT vorhanden ist. Sie werden ständig Probleme haben, wenn Sie Code-Schnipsel ausleihen und sie ständig reparieren. Halten Sie einfach Ihre benutzerdefinierten und geliehenen Sachen in begrenztem Umfang, wie sie sein sollten, und seien Sie SEHR sparsam mit Globals (ehrlich gesagt sollten Globals fast immer der letzte Ausweg sein, um "jetzt kompilieren, später vernünftig sein"). Ich glaube wirklich, dass es ein schlechter Rat von Ihrem Lehrer ist, weil die Verwendung von std sowohl für "cout" als auch für "std::cout" funktioniert, aber die NICHT-Verwendung von std funktioniert nur für "std::cout". Sie werden nicht immer das Glück haben, Ihren gesamten Code selbst zu schreiben.

HINWEIS: Konzentrieren Sie sich nicht zu sehr auf Fragen der Effizienz, bis Sie ein wenig über die Funktionsweise von Compilern gelernt haben. Mit ein wenig Erfahrung im Programmieren müssen Sie nicht viel über sie lernen, bevor Sie erkennen, wie sehr sie in der Lage sind, guten Code in etwas Einfaches zu verallgemeinern. Genauso einfach, wie wenn Sie das Ganze in C geschrieben hätten. Guter Code ist nur so komplex, wie er sein muss.

2 Stimmen

In Anbetracht der Tatsache, dass viele Leute keine Ahnung von nützlichen Standardbibliotheksfunktionen zu haben scheinen (das Neuerfinden von Dingen aus <algorithm> ), scheint es etwas weit hergeholt, sich vorzustellen, dass dieselben Personen diese Kennzeichnungen zuverlässig vermeiden könnten. Sehen Sie sich Ihren eigenen Code an und sagen Sie mir, dass Sie nie eine Variable oder Funktion mit dem Namen count . Oder distance o log , destroy , launch , visit , beta , sample , messages , clamp , erase , copy , modulus , left , usw. Ganz zu schweigen von all den Identifikatoren, die noch nicht in std die Ihren Code zerstören, wenn C++35 herauskommt...

5voto

Brett Hale Punkte 20842

Darauf gibt es eine ganz einfache Antwort: Es ist die defensive Programmierung. Sie wissen, dass die Verwendung von std::size_t , std::cout , usw., könnte ein wenig leichter gemacht werden mit using namespace std; - Ich hoffe, Sie müssen nicht davon überzeugt werden, dass eine solche Richtlinie nichts in einer Kopfzeile zu suchen hat! Innerhalb einer Übersetzungseinheit könnten Sie jedoch in Versuchung geraten...

Die Typen, Klassen usw., die Teil der std Namespace mit jeder C++-Revision zunehmen. Es gibt zu viele potentielle Mehrdeutigkeiten, wenn man die std:: Qualifikant. Es ist vollständig sinnvoll, den Qualifier für Namen innerhalb von std die Sie häufig verwenden werden, z. B., using std::fprintf; oder, was wahrscheinlicher ist, etwas wie: using std::size_t; - aber es sei denn, es handelt sich um bereits gut verstandene Teile der Sprache (oder speziell der std Wrapping der C-Bibliothek), verwenden Sie einfach den Qualifier.

Wenn Sie Folgendes verwenden können typedef in Verbindung mit auto y decltype inferencing, gibt es wirklich nichts zu gewinnen von einer Lesbarkeit / Wartungsfreundlichkeit Perspektive.

5voto

#include <iostream>

using namespace std;

int main() {
  // There used to be
  // int left, right;
  // But not anymore

  if (left != right)
    std::cout << "Excuse me, WHAT?!\n";
}

Also, warum? Weil es bringt Bezeichner ein, die sich mit häufig verwendeten Variablennamen überschneiden und lässt diesen Code kompilieren, wobei er so interpretiert wird, dass er bedeutet if (std::left != std::right) .

PVS-Studio kann einen solchen Fehler mit Hilfe der Diagnose V1058 finden: https://godbolt.org/z/YZTwhp (Danke, Andrey Karpov!!).

An die cppcheck-Entwickler: Vielleicht möchten Sie dies markieren. Das war ein Kracher.

4voto

Timon Paßlick Punkte 175

Um ehrlich zu sein, ist das für mich so, als würde man über die Anzahl der Leerzeichen für die Einrückung diskutieren.

Die Verwendung von Direktiven in Kopfzeilen verursacht Schaden. Aber in C++-Dateien? Vielleicht, wenn Sie zwei Namespaces gleichzeitig verwenden. Aber wenn Sie einen verwenden, geht es mehr um den Stil als um echte Effizienz.

Wissen Sie, warum Themen über Einrückungen so beliebt sind? Jeder kann etwas dazu sagen und sich dabei sehr klug und erfahren anhören.

1 Stimmen

Es braucht nur ein Beispiel, um das Gegenteil zu beweisen: if (left != right) kompiliert mit using std::namespace; ohne dass es eine left noch right in Ihrem Code. Es ist ein echter Fehler, auf den ich beim Refactoring eines echten Projekts gestoßen bin. std ist so voll von gebräuchlichen Namen, dass Fehler wie dieser in vielen kommerziellen Codebasen vorkommen, bei denen die ursprünglichen Werte ausgeklammert wurden und die nun ungültigen Verwendungen bestehen bleiben. Dies war ein Problem in einem .cpp Quelldatei, nicht in einer Kopfzeile. Dies ist keine Frage der Meinung. Finden Sie nur ein einziges Beispiel, bei dem es zu stillen Fehlern kommt, und das Spiel ist vorbei. Verbieten Sie dieses Zeug.

0 Stimmen

Stimmt, das habe ich nicht bedacht, als ich diese Antwort schrieb.

0 Stimmen

In cpp-Dateien: Sie werden überrascht sein, was hier mit UnityBuilds passieren kann... Sie sind nicht so ungewöhnlich...

4voto

harris Punkte 1405

Ja, der Namensraum ist wichtig. In meinem Projekt musste ich einmal eine var-Deklaration in meinen Quellcode importieren, aber beim Kompilieren kam es zu Konflikten mit einer anderen Drittanbieter-Bibliothek.

Am Ende musste ich das Problem mit anderen Mitteln umgehen und den Code unübersichtlicher machen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X