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.

35voto

Yelonek Punkte 603

Ich halte das auch für eine schlechte Praxis. Warum eigentlich? Eines Tages dachte ich, dass die Funktion eines Namensraums darin besteht, Dinge aufzuteilen, also sollte ich es nicht verderben, indem ich alles in einen globalen Sack werfe.

Wenn ich jedoch häufig 'cout' und 'cin' verwende, schreibe ich: using std::cout; using std::cin; in der .cpp-Datei (niemals in der Header-Datei, da sie sich mit #include ). Ich glaube, dass niemand, der bei Verstand ist, jemals einen Strom nennen wird. cout ou cin . ;)

8 Stimmen

Das ist ein Ortsansässiger, der Erklärung eine ganz andere Sache als eine Verwendung Richtlinie .

29voto

Preet Sangha Punkte 62622

Es geht um die Beherrschung der Komplexität. Durch die Verwendung des Namespace werden Dinge hineingezogen, die Sie nicht wollen, was die Fehlersuche möglicherweise erschwert (ich sage: möglicherweise). Die Verwendung von std:: überall ist schwieriger zu lesen (mehr Text und all das).

Pferde für den Kurs - managen Sie Ihre Komplexität so, wie Sie es am besten können und sich dazu in der Lage fühlen.

0 Stimmen

"Die Verwendung des Namespace zieht Dinge an, die Sie nicht wollen, und erschwert so möglicherweise die Fehlersuche (ich sage: möglicherweise)." Die Verwendung des Namespace "zieht" nichts hinein. Die Fehlersuche wird nicht beeinträchtigt.

0 Stimmen

Das hängt davon ab, wie man die Dinge definiert. Im obigen Kontext bedeutete die Verwendung, dass alles im std::-Namensraum als zum Geltungsbereich gehörig betrachtet wurde. Jeder Bezeichner könnte aus diesem Namespace stammen, also muss man das beim Lesen von Code berücksichtigen. Dies führt zu einer Mehrdeutigkeit, die einfach nicht existiert, wenn man nur bei Bedarf auf etwas mit Namespace verweist. Alles, was die kognitive Belastung des Lesers reduziert (z. B. die überwiegende Zeit der Lebensdauer des Codes), ist eine gute Sache, und umgekehrt ist alles, was die Belastung erhöht, eine schlechte Sache. Daher auch mein Disclaimer am Ende.

0 Stimmen

Die Verwendung von "pull things in" in diesem Zusammenhang erweckt den falschen Eindruck - es wird der Eindruck erweckt, dass zusätzliche Deklarationen im Namespace in das Programm aufgenommen werden, unabhängig davon, wie Sie es gemeint haben. Ich stimme dem zu, was Sie über die kognitive Belastung gesagt haben.

23voto

Ron Warholic Punkte 9894

Erwägen Sie

// myHeader.h
#include <sstream>
using namespace std;

// someoneElses.cpp/h
#include "myHeader.h"

class stringstream {  // Uh oh
};

Beachten Sie, dass dies ein einfaches Beispiel ist. Wenn Sie Dateien mit 20 Includes und anderen Importen haben, müssen Sie eine ganze Reihe von Abhängigkeiten durchgehen, um das Problem zu lösen. Das Schlimmste daran ist, dass Sie je nach den widersprüchlichen Definitionen Fehler in anderen Modulen erhalten können, die in keinem Zusammenhang stehen.

Es ist nicht schrecklich, aber Sie ersparen sich Kopfschmerzen, wenn Sie es nicht in Header-Dateien oder im globalen Namensraum verwenden. Es ist wahrscheinlich in Ordnung, es in sehr begrenzten Bereichen zu tun, aber ich hatte noch nie ein Problem damit, die zusätzlichen fünf Zeichen einzugeben, um zu verdeutlichen, woher meine Funktionen kommen.

0 Stimmen

In den Kopfzeilen sicher, aber was ist, wenn using namespace std nur in den Implementierungsdateien vorhanden ist?

20voto

Dustin Getz Punkte 20462
  1. Sie müssen in der Lage sein, Code zu lesen, der von Leuten geschrieben wurde, die andere Vorstellungen von Stil und bewährten Verfahren haben als Sie.

  2. Wenn Sie nur cout wird niemand verwirrt. Wenn aber viele Namespaces im Umlauf sind und Sie diese Klasse sehen und nicht genau wissen, was sie tut, wirkt die Angabe des Namespaces wie eine Art Kommentar. Man kann auf den ersten Blick sehen, "oh, das ist eine Dateisystem-Operation" oder "das macht Netzwerkkram".

14voto

Carl Punkte 41134

Ich stimme mit den anderen hier überein, aber ich möchte die Bedenken bezüglich der Lesbarkeit ansprechen - Sie können all das vermeiden, indem Sie einfach Typendefinitionen am Anfang Ihrer Datei, Funktion oder Klassendeklaration verwenden.

Ich verwende sie in der Regel in meiner Klassendeklaration, da die Methoden einer Klasse in der Regel mit ähnlichen Datentypen (den Mitgliedern) arbeiten und ein Typedef die Möglichkeit bietet, einen Namen zu vergeben, der im Zusammenhang mit der Klasse sinnvoll ist. Dies erleichtert die Lesbarkeit der Definitionen der Klassenmethoden.

// Header
class File
{
   typedef std::vector<std::string> Lines;
   Lines ReadLines();
}

und bei der Umsetzung:

// .cpp
Lines File::ReadLines()
{
    Lines lines;
    // Get them...
    return lines;
}

im Gegensatz zu:

// .cpp
vector<string> File::ReadLines()
{
    vector<string> lines;
    // Get them...
    return lines;
}

oder:

// .cpp
std::vector<std::string> File::ReadLines()
{
    std::vector<std::string> lines;
    // Get them...
    return lines;
}

0 Stimmen

Nur eine kleine Anmerkung: Obwohl typedef nützlich ist, würde ich erwägen, eine Klasse zu erstellen, die Lines repräsentiert, anstatt typedef zu verwenden.

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