Namespaceproblem
-
Hallo,
hier mal etwas, was ich nicht nachvollziehen kann:
ich habe 4 Dateien://Foo.hpp #include "Bar.hpp" namespace blubb { class Benutzung { int set(); }; } //Foo.cpp #include "Foo.hpp" using namespace blubb; int Benutzung::set() { ichWerdeBenutzt(); return 0; } //Bar.hpp namespace blubb { bool ichWerdeBenutzt(); } //Bar.cpp #include "Bar.hpp" using namespace blubb; bool ichWerdeBenutzt() { //do somthing... }Der Compiler gibt mit bei jedem Aufruf von
ichWerdeBenutzt()eine Fehlermeldung aus:undefined reference to ...Das Problem lässt sich dadurch beheben, dass ich in Bar.cpp schreibe:
//Bar.cpp #include "Bar.hpp" using namespace blubb; bool blubb::ichWerdeBenutzt() { //do somthing... }Das versteh ich nicht. Warum muss ich den Namenraum vor die Funktion schreiben, wenn ich obendrüber schreibe, dass der Compiler den Namensraum benutzen soll?
MfG. Ich
-
Das versteh ich nicht. Warum muss ich den Namenraum vor die Funktion schreiben, wenn ich obendrüber schreibe, dass der Compiler den Namensraum benutzen soll?
Na, das ist einfach. Schau dir mal das an:
bool ichWerdeBenutzt() { //do somthing... } bool blubb::ichWerdeBenutzt() { //do somthing... }Das Eine ist eine Funktion die im namespace blubb liegt, die andere liegt im globalen Namensraum.
Wenn du also nun sowas hast:
using namespace blubb; using namespace foo; bool ichWerdeBenutzt() { //do somthing... }Wie soll der Compiler dann unterscheiden, ob das ein blubb::ichWerdeBenutzt, ein foo::ichWerdeBenutzt oder ein ::ichWerdeBenutzt ist?
-
das hier ist falsch:
#include "Foo.hpp" using namespace blubb; int Benutzung::set() { ichWerdeBenutzt(); return 0; }ein using reicht hier _nicht_
so sollte es aussehen:#include "Foo.hpp" namespace blubb{ int Benutzung::set() { ichWerdeBenutzt(); return 0; } } //namespace blubbbb
-
Das "using namespace ..." besagt nur, daß für den Lookup die Namen aus diesem Namensbereich mit benutzt werden sollen, aber für die Definition benötigst du die konkrete Zuordnung.
Eine andere Möglichkeit (äquivalent zu den Header-Dateien) wäre://Bar.cpp #include "Bar.hpp" namespace blubb { bool ichWerdeBenutzt() { //do something... } } // namespace blubbDies macht jedoch Probleme, wenn du innerhalb dieser Funktionsdefinitionen noch lokale Definitionen (o.a.) benötigst.
Üblich ist daher die Form:
bool blubb:ichWerdeBenutzt()auch wenn es mehr Schreibarbeit bedeutet...
-
Also gilt die Regel, dass ich bei Definitionen
namespace xyz{...}benutze, und bei Aufrufen/Verwendungenusing namespace xyz?Wie soll der Compiler dann unterscheiden, ob das ein blubb::ichWerdeBenutzt, ein foo::ichWerdeBenutzt oder ein ::ichWerdeBenutzt ist?
Wäre das der Fall, hätte der Compiler/Linker mir nicht
undefinded referencesondernxyz is ambigousausgegeben.
-
Ich glaube, dass das Problem hier eine falsche Definition von
using namespaceist. Also ChristophLu hat hier eine falsche Vorstellung vonusing namespace.using namespacesagt nicht aus, dass der Kompiler nun diesen Namensraum verwenden soll. Es sagt dem Kompiler, dass er den Namensraum im aktuellen Namensraum ausleeren soll. Wenn wir also folgendes haben "using namespace xyz" und wir befinden uns im Namensraumbbb, dann wir alles was sich im Namensraumxyzbefindet, in den Namensraumbbbgeleert. Deshalb sage ich auch immer, dass manusing namespacesehr vorsichtig und überlegt verwenden sollte.Man kann schliesslich auch bei der Verwendung ohne
using namespacevorgehen:#include <iostream> int main() { std::cout << "Hello World!" << std::endl; //^^^^^ explizite Angabe ^^^^^ return 0; }Zusammengefasst:
"using namespace" heisst nicht "verwende Namensraum", sondern heisst "leere Namensraum hier aus".Grüssli
-
ah ... achso. Gut, also hab ichs falsch verstanden. Das erklärt auch manch anderes Problem

Danke Dravere!