Was genau ist ein Namensraum und warum ist er notwendig?

Lesezeit: 6 Minuten

Benutzer-Avatar
Programmierer

Ich lerne gerade C++, und am Anfang jedes Projekts setzt mein Lehrer eine Zeile, die besagt:

using namespace std;

Ich verstehe, dass es Sie davon abhält, Funktionen in Headern aufzurufen, die Sie mit ihrem Header-Namen wie iostream::stdout einfügen, und stattdessen einfach stdout aufrufen.

Aber was genau sagt die Zeile C++ zu tun. Was ist ein Namespace und was ist std?

Ich bin neben Python auch neu in der Programmierung, daher ist der Wechsel zu einem neuen Paradigma für mich sehr verwirrend.

  • Siehe auch: stackoverflow.com/questions/1452721/…

    – TC

    22. August 2015 um 22:00 Uhr

  • Da Sie Python verwendet haben, stellen Sie es sich als das C++-Analogon von vor from std import *.

    – TC

    22. August 2015 um 22:02 Uhr

  • Sie fragten, warum dies eine schlechte Praxis sei. Ich habe einfach gefragt, was es bedeutet und was ein Namespace @TC ist

    – Programmierer

    22. August 2015 um 22:02 Uhr

  • @banana Der Sinn dieses Links besteht darin, ihn Ihrem Lehrer als Treibstoff zur Verfügung zu stellen, um schlechte Praktiken bei der Zucht ihrer Schüler zu unterdrücken.

    – WhozCraig

    22. August 2015 um 22:07 Uhr

  • Ihr Ausbilder ist ein Werkzeug und nicht das richtige für den Job.

    – Kapitän Offensichtlich

    22. August 2015 um 22:10 Uhr

Von cpreference.com:

Namespaces bieten eine Methode zum Verhindern von Namenskonflikten in großen Projekten.

Innerhalb eines Namespace-Blocks deklarierte Symbole werden in einem benannten Gültigkeitsbereich platziert, der verhindert, dass sie mit identisch benannten Symbolen in anderen Gültigkeitsbereichen verwechselt werden.

Mehrere Namespace-Blöcke mit demselben Namen sind zulässig. Alle Deklarationen innerhalb dieser Blöcke werden im benannten Geltungsbereich deklariert.

Ein Namensraum dient dazu, Namenskonflikte zu vermeiden, wie sie beispielsweise die Standardbibliothek definiert sort() Aber das ist ein wirklich guter Name für eine Sortierfunktion, dank Namespaces können Sie Ihre eigenen definieren sort() da es sich nicht im selben Namensraum wie der Standard befinden wird.

Die using-Direktive weist den Compiler an, diesen Namespace im aktuellen Gültigkeitsbereich zu verwenden, damit Sie dies tun können

int f(){
    std::cout << "out!" << std::endl;
}

oder:

int f(){
    using namespace std;
    cout << "out!" << endl;
}

Es ist praktisch, wenn Sie viele Dinge aus einem anderen Namespace verwenden.

Quelle: Namespaces – cpreference.com

  • Wenn ich also eine Namespace-Anweisung in einer Funktion habe, kann ich std-Funktionen ohne ihren Namespace-Namen und einen doppelten Doppelpunkt aufrufen, oder gilt die Namespace-Anweisung nur für ihren lexikalischen Codeblock

    – Programmierer

    22. August 2015 um 22:35 Uhr

  • was bedeutet, dass ich außerhalb der Funktion stdout anstelle von iostream::stdout sagen kann

    – Programmierer

    22. August 2015 um 22:37 Uhr

  • @banana es folgt den üblichen Bereichsregeln

    – Alejandro Diaz

    23. August 2015 um 20:49 Uhr

Benutzer-Avatar
2785528

Aber was genau sagt die Zeile C++ zu tun. Was ist ein Namespace und was ist std?

std ist ein Namespace.

Ein Namespace ist eine Sammlung von Symbolen.

Die Zeile weist Ihren C++-Compiler an

a) Durchsuchen Sie die enthaltenen Teile des Namensraums std (dh iostream, iomanip), wenn

b) es findet keine Definition eines Symbols (wie (std::) cout ) vor

c) Erklären des Symbols für unbekannt.

Die Auflösung von Namenskonflikten (wie in den anderen Antworten beschrieben) ist wahrscheinlich das wichtigste angesprochene Thema.

Was mir an Namespaces am besten gefällt, ist, dass die Namespace-Inhalte (Klassen und Funktionen) über mehrere Header-Dateien hinweg hinzugefügt werden können. (Im Gegensatz zu einer Klasse, die komplett in einer Header-Datei stehen muss).

Also tragen iostream, iomanip, string, stringstream jeweils unabhängig voneinander Klassen und Code zum std-Namespace bei.

Und so kann ich die meisten meiner Tools in separaten Dateien aufbewahren und sie dennoch “logisch” in einem Namensraum zusammenführen.

Zum Beispiel: Ich habe ein RAM-basiertes Protokoll mit fester Größe in der Datei dtb_log.hh, und eine kurze Übersicht sieht so aus:

// Name:        dtb_log.hh
//
#ifndef DTB_LOG_HH
#define DTB_LOG_HH

namespace DTB  // <acronym description>
{    
   class Log
   {
   public:
       // ...

   }; // class Log

} // namespace DTB 

#endif // DTB_LOG_HH

Ich habe auch ein (selten verwendetes und in diesem Fall verwandtes) Dienstprogramm in der Datei dtb_mem_tag.hh

// Name:         dtb_mem_tag.hh
//
#ifndef DTB_MEM_TAG_HH
#define DTB_MEM_TAG_HH


namespace DTB    // <acronym name def>
{
   class MemTag
   {
   public:
   // ...
   };  // class MemTag

} // namespace DTB    

#endif // DTB_MEM_TAG_HH

Die Verwendung von DTB::MemTag und DTB::Log ist so einfach wie das Einfügen der entsprechenden #include-Header-Dateien.

Und in der Anwendung, in der diese verwendet werden, kann jede Verwendung von beiden eindeutig mit dem Präfix „DTB::“ gekennzeichnet werden.


Jeder DTB-Code „Evolution“, der bearbeitet werden muss, befindet sich in meinem „dtb“-Namespace-Verzeichnis.

Daher kann ich allein anhand der Dateidatumsstempel erkennen, wo sich der Übergang zu Ubuntu 64 auf meine Tools ausgewirkt hat. Zum Beispiel kann ich sehen, dass dtb_termselect.xx (für Arduino-Interaktionscode) aktualisiert wurde, ebenso wie dtb_popen.xx, dtb_pause und mehrere andere.


In einer Teamumgebung (vor einiger Zeit) haben wir verschiedene Möglichkeiten zur gemeinsamen Nutzung von Namespaces diskutiert. Im Allgemeinen wurde dies nicht gut aufgenommen … zu schwierig, sich darauf zu einigen, wie.

Aber unter den diskutierten Ideen war die Idee, den Namensraum als Signatur eines beitragenden Autors zu verwenden. So wurde DTB (Mine) und KTS (Ken’s Transition Service) und einige andere geschaffen. Auch davon waren nicht alle begeistert.

  • FYI – “DTB” steht für Doug’s Tool Box,

    – 2785528

    9. März 2019 um 20:51 Uhr

Beginnen wir mit einem Problem, um zu erklären, was Namespaces sind. Wir alle wissen, dass wir keine Funktionen, Klassen oder andere Arten von Daten haben können, die den gleichen Namen haben. Nehmen wir an, wir haben zwei Bibliotheken, die beide eine Funktion hinzufügen, sagen wir print(). Beide haben eine unterschiedliche Funktion, sind aber bei der Benennung nicht zu unterscheiden. Hier kommen Namensräume ins Spiel. Ein Namensraum ist wie das Hinzufügen eines neuen Gruppennamens, dem Sie Funktionen und andere Daten hinzufügen können, damit er unterscheidbar wird.

namespace bla
{
  void print()
  {
    // function bla::print()
  }
}

namespace blabla
{
  void print()
  {
    // function blabla::print()
  }
}

Nun, wie Sie sehen können, gibt es zwei Funktionen mit dem Namen print, aber aufgrund von Namensräumen gibt es keinen Namenskonflikt. Die erste Funktion würde aufgerufen werden mit: bla::print() und die zweite mit blabla::print().

std ist eine Abkürzung für Standard. std ist der Standardnamensraum. cout, cin und viele andere Dinge sind darin definiert. (Das bedeutet, dass eine Möglichkeit, sie aufzurufen, die Verwendung von std::cout und std::cin ist.)

Das Schlüsselwort mit technisch bedeutet, verwenden Sie dies, wann immer Sie können. Dies bezieht sich in diesem Fall auf den std-Namespace. Wenn also der Computer auf cout, cin, endl oder irgendetwas in der Art stößt, liest er es als std::cout, std::cin oder std::endl.

Wenn Sie den std-Namespace nicht verwenden, versucht der Computer, cout oder cin so aufzurufen, als ob es nicht in einem Namespace definiert wäre (wie die meisten Funktionen in Ihren Codes). Da es dort nicht existiert, versucht der Computer, etwas anzurufen, das es nicht gibt! Daher tritt ein Fehler auf.

1012730cookie-checkWas genau ist ein Namensraum und warum ist er notwendig?

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

Privacy policy