“using namespace” in C++-Headern [duplicate]

Lesezeit: 8 Minuten

In allen unseren C++-Kursen setzen immer alle Lehrer using namespace std; gleich nach dem #includes in ihren .h Dateien. Dies scheint mir gefährlich zu sein, da ich durch Einfügen dieses Headers in ein anderes Programm den Namespace in mein Programm importiert bekomme, möglicherweise ohne es zu merken, zu beabsichtigen oder zu wollen (Header-Einbindung kann sehr tief verschachtelt sein).

Meine Frage ist also doppelt: Habe ich recht damit using namespace sollte nicht in Header-Dateien verwendet werden, und/oder gibt es eine Möglichkeit, dies rückgängig zu machen, etwa so:

//header.h
using namespace std {
.
.
.
}

Eine weitere Frage in die gleiche Richtung: Sollte eine Header-Datei #include alle Header, denen es entspricht .cpp Datei benötigt, nur diejenigen, die für die Header-Definitionen benötigt werden und lassen die .cpp Datei #include der Rest oder keiner und deklariert alles, was es braucht, als extern?
Die Argumentation hinter der Frage ist die gleiche wie oben: Ich möchte keine Überraschungen beim Einschließen .h Dateien.

Und wenn ich recht habe, ist das ein häufiger Fehler? Ich meine in der realen Programmierung und in “echten” Projekten da draußen.

Danke.

  • stackoverflow.com/questions/1265039/using-std-namespace

    – Richard Inglis

    1. Mai 2011 um 15:53 ​​Uhr

  • als Randbemerkung, wenn Sie Namenskollisionen aufgrund von bekommen using namespace Anweisungen, dann könnten Sie den vollständig qualifizierten Namen verwenden, um das Problem zu lösen.

    – Marius Bancila

    1. Mai 2011 um 16:08 Uhr

using namespace in C Headern duplicate
Markus B

Sie sollten auf keinen Fall verwenden using namespace in Headern aus genau dem Grund, den Sie sagen, dass es die Bedeutung von Code in anderen Dateien, die diesen Header enthalten, unerwartet ändern kann. Es gibt keine Möglichkeit, a rückgängig zu machen using namespace Das ist ein weiterer Grund, warum es so gefährlich ist. Ich benutze normalerweise nur grep oder dergleichen, um dies sicherzustellen using namespace wird nicht in Kopfzeilen aufgerufen, anstatt etwas Komplizierteres zu versuchen. Wahrscheinlich kennzeichnen statische Codeprüfer dies auch.

Der Header sollte nur die Header enthalten, die er kompilieren muss. Eine einfache Möglichkeit, dies zu erzwingen, besteht darin, den eigenen Header jeder Quelldatei immer als erstes vor allen anderen Headern einzufügen. Dann wird die Quelldatei nicht kompiliert, wenn der Header nicht in sich geschlossen ist. In einigen Fällen, z. B. in Bezug auf Implementierungsdetailklassen innerhalb einer Bibliothek, können Sie stattdessen Vorwärtsdeklarationen verwenden #include weil Sie die volle Kontrolle über die Definition einer solchen vorwärts deklarierten Klasse haben.

Ich bin mir nicht sicher, ob ich es als gewöhnlich bezeichnen würde, aber es taucht definitiv hin und wieder auf und wird normalerweise von neuen Programmierern geschrieben, die sich der negativen Folgen nicht bewusst sind. Normalerweise kümmert sich nur ein wenig Aufklärung über die Risiken um alle Probleme, da es relativ einfach zu beheben ist.

  • sind wir frei zu benutzen using Aussagen in unserem .cpp Dateien? der 3rdPartyLib::BigClassName<3rdPartyLib::AnotherBigName,3rdPartyLib::AnotherBigName>::Iterators sind Tod für die Fingerspitzen.

    – Chris

    11. März 2018 um 11:42 Uhr


  • und wie sollten wir das rationalisieren template Funktionen – welche sollen in den Headern stehen? typedefs?

    – Chris

    11. März 2018 um 11:43 Uhr

  • @donlan, anscheinend hast du eine ganze Weile keine Antwort erhalten … Ja, du kannst verwenden using Aussagen darin .cpp Dateien ohne große Bedenken, da der Geltungsbereich auf genau diese Datei beschränkt ist, aber niemals vor einer #include Aussage. Was die in Headern definierten Template-Funktionen betrifft, kenne ich leider keine andere gute Lösung, als nur den Namensraum auszuschreiben … Vielleicht könnten Sie a using Erklärung in einem separaten Geltungsbereich { /* using statement in between brackets */ }das würde zumindest verhindern, dass die aktuelle Datei maskiert wird.

    – tjwrona1992

    31. Mai 2019 um 4:12 Uhr


using namespace in C Headern duplicate
Andi Thomas

Punkt 59 bei Sutter und Alexandrescu “C++-Codierungsstandards: 101 Regeln, Richtlinien und Best Practices”:

59. Schreiben Sie keine Namespace-Usings in eine Header-Datei oder vor ein #include.

Namensraum usings sind für Ihre Bequemlichkeit, nicht für Sie, um sie anderen aufzubürden: Schreiben Sie niemals a using Erklärung oder a using Direktive vor einem #include Richtlinie.

Folgerung: Schreiben Sie in Header-Dateien nicht auf Namespace-Ebene using Richtlinien bzw using Erklärungen; qualifizieren Sie stattdessen explizit alle Namen für den Namensraum.

Eine Header-Datei ist ein Gast in einer oder mehreren Quelldateien. Eine Header-Datei, die enthält using Direktiven und Deklarationen bringt auch seine rüpelhaften Kumpels mit.

EIN using Erklärung bringt einen Kumpel mit. EIN using Richtlinie bringt alle Freunde im Namensraum ein. Die Verwendung Ihrer Lehrer using namespace std; ist eine using-Direktive.

Im Ernst, wir haben Namensräume, um Namenskonflikte zu vermeiden. Eine Header-Datei soll eine Schnittstelle bereitstellen. Die meisten Header wissen nicht, welcher Code sie jetzt oder in Zukunft enthalten kann. Hinzufügen using Anweisungen für die interne Bequemlichkeit innerhalb des Headers schiebt diese bequemen Namen allen potenziellen Kunden dieses Headers unter. Das kann zu Namenskonflikten führen. Und es ist einfach nur unhöflich.

using namespace in C Headern duplicate
Mike O’Connor

Sie müssen vorsichtig sein, wenn Sie Header in Header einfügen. In großen Projekten kann es zu einer sehr verworrenen Abhängigkeitskette kommen, die größere/längere Neuaufbauten auslöst, als eigentlich notwendig wären. Kasse Dieser Beitrag und seine Nachfolge um mehr über die Bedeutung einer guten physischen Struktur in C++-Projekten zu erfahren.

Sie sollten Header nur dann in einen Header einfügen, wenn dies unbedingt erforderlich ist (wenn die vollständige Definition einer Klasse benötigt wird), und die Vorwärtsdeklaration verwenden, wo immer Sie können (wenn die Klasse ein Zeiger oder eine Referenz sein muss).

Was Namensräume angeht, neige ich dazu, den expliziten Namensraumbereich in meinen Header-Dateien zu verwenden und nur a using namespace in meinen cpp-Dateien.

  • wie rationalisiert man template Funktionsdeklaration? das muss im Header stehen, oder?

    – Chris

    11. März 2018 um 11:44 Uhr

1647177610 508 using namespace in C Headern duplicate
Jonathan Leffler

Sehen Sie sich die Codierungsstandards des Goddard Space Flight Center (für C und C++) an. Das gestaltet sich etwas schwieriger als früher – siehe die aktualisierten Antworten auf die SO-Fragen:

  • Soll ich #include in Headern verwenden?
  • Autarke Header in C und C++

Der GSFC-C++-Codierungsstandard sagt:

§3.3.7 Jede Header-Datei muss #include die Dateien, die es kompilieren muss, anstatt Benutzer dazu zu zwingen #include die benötigten Dateien. #includes ist auf das zu beschränken, was der Header benötigt; andere #includes sollte in der Quelldatei platziert werden.

Die erste der Querverweisfragen enthält nun ein Zitat aus dem GSFC-C-Codierungsstandard und die Begründung, aber der Inhalt ist am Ende derselbe.

In Bezug auf “Gibt es eine Möglichkeit, dies rückgängig zu machen [a using declaration]?”

Ich finde es sinnvoll, darauf hinzuweisen using Deklarationen sind vom Geltungsbereich betroffen.

#include <vector>

{   // begin a new scope with {
    using namespace std;
    vector myVector;  // std::vector is used
}   // end the scope with }

vector myOtherVector;   // error vector undefined
std::vector mySTDVector // no error std::vector is fully qualified

Also effektiv ja. Durch die Einschränkung des Umfangs der using Erklärung ihre Wirkung nur in diesem Bereich anhält; es wird “rückgängig gemacht”, wenn dieser Geltungsbereich endet.

Wenn das using -Deklaration in einer Datei außerhalb eines anderen Bereichs deklariert wird, hat sie einen Dateibereich und wirkt sich auf alles in dieser Datei aus.

Im Fall einer Header-Datei, wenn die using -Deklaration im Dateibereich ist, erstreckt sich dies auf den Bereich jeder Datei, in der der Header enthalten ist.

  • du scheinst der einzige zu sein, der die eigentliche frage verstanden hat… aber meine kompilierung ist nicht sehr glücklich darüber, dass ich innerhalb der klasse deceleration verwende.

    – rostiges Papier

    8. Januar 2017 um 16:34 Uhr

  • Diese Antwort könnte noch besser gemacht werden, indem das Problem mit der Idee des OP erklärt wird, wie der Umfang funktionieren sollte (wie die namespace Deklarationszeug) vs. wie es tatsächlich funktioniert (wie eine Variable). {} es einzuschließen schränkt seinen Geltungsbereich ein, {} nachdem es nichts damit zu tun. Das ist eine zufällige Art und Weise, dass die using namespace wird global angewendet.

    – Taft

    20. November 2018 um 8:41 Uhr

Da hast du Recht using namespace im Header ist gefährlich. Ich weiß nicht, wie ich das rückgängig machen kann. Es ist leicht zu erkennen, aber suchen Sie einfach danach using namespace in Header-Dateien. Aus diesem letzten Grund ist es in realen Projekten ungewöhnlich. Erfahrenere Mitarbeiter werden sich schnell beschweren, wenn jemand so etwas macht.

In echten Projekten versuchen die Leute, die Menge der eingebundenen Dateien zu minimieren, denn je weniger Sie einbinden, desto schneller wird kompiliert. Das spart allen Zeit. Wenn die Header-Datei jedoch davon ausgeht, dass etwas davor eingefügt werden soll, sollte sie es selbst enthalten. Andernfalls macht es Header nicht in sich geschlossen.

  • du scheinst der einzige zu sein, der die eigentliche frage verstanden hat… aber meine kompilierung ist nicht sehr glücklich darüber, dass ich innerhalb der klasse deceleration verwende.

    – rostiges Papier

    8. Januar 2017 um 16:34 Uhr

  • Diese Antwort könnte noch besser gemacht werden, indem das Problem mit der Idee des OP erklärt wird, wie der Umfang funktionieren sollte (wie die namespace Deklarationszeug) vs. wie es tatsächlich funktioniert (wie eine Variable). {} es einzuschließen schränkt seinen Geltungsbereich ein, {} nachdem es nichts damit zu tun. Das ist eine zufällige Art und Weise, dass die using namespace wird global angewendet.

    – Taft

    20. November 2018 um 8:41 Uhr

Du hast recht. Und jede Datei sollte nur die Header enthalten, die von dieser Datei benötigt werden. Was “ist es in realen Projekten üblich, Dinge falsch zu machen?” – Oh ja!

997840cookie-check“using namespace” in C++-Headern [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy