c++ In übergeordneten Namespace auf variable zugreifen

Gast #6413985
Lesenswert?

Hi Leute,

ich wollte mal C++ Namensräumen arbeiten. Bin mir nur nicht sicher ob 
ich mich mit denen anfreunden kann…

Um die Dateien klein und übersichtlich zu halten wollte ich die unteren 
Namensräume in andere Dateien verschieben. Allerdings ergibt sich daraus 
ein Problem.
Ich kann auf die im oberen Namensraum „globalen“ Variablen nicht 
zugreifen, wenn ich die Implementierung der unteren Namensräume in 
andere Dateien verschiebe.
1
//Bsp.1
2
//Das funktioniert da var vor dem Namensraum b1 steht.
3
//Deswegen kann die Funktion b1::get() darauf zugreifen. 
4
namespace b {
5
  volatile bool var;
6

7
  namespace b1 {
8
  bool get(){
9
    return b::var;
10
  }
11
  //usw...
12
  }  // namespace b1
13
  //usw...
14
}  // namespace b

Wenn ich es in zwei Dateien aufteile funktioniert es nicht mehr.
Fehler: 'var' is not a member of 'a'.

a.cpp
1
//Bsp2
2
namespace a {
3
  volatile bool var;
4
  namespace a1 {
5
    bool get();
6
  }  // namespace a1
7
  //usw...
8
}  // namespace a

a1.cpp
1
//Bsp2
2
namespace a {
3
namespace a1 {
4
bool get(){
5
  return a::var;
6
}
7
//usw...
8
}  // namespace aa
9
}

Kann es so überhaupt so umgesetzt werden wie ich es mir vorstelle?
Gast #6414019
Lesenswert?

WasSindSchonNamen schrieb:
> Ich kann auf die im oberen Namensraum „globalen“ Variablen nicht
> zugreifen, wenn ich die Implementierung der unteren Namensräume in
> andere Dateien verschiebe.
Das hat erstmal nichts mit namespaces zu tun. Wenn du die namespaces aus 
a.cpp und a1.cpp entfernst funktioniert das Beispiel ja auch nicht. Du 
müsstes erst in a1.cpp so etwas wie extern volatile bool var; 
hinzufügen, damit var in a1.cpp bekannt ist. Das gleiche gilt mit 
namespaces, nur dass eben die namespaces noch angegeben werden müssen.
#6414031
Lesenswert?

Hm, das ist ein X-Y-Problem. Wozu soll das ganze gut sein?

Wenn du eine "Singleton-Variable" haben willst, mach sowas:

foo.h
Foo& getFoo();

foo.cpp
Foo& getFoo() {
 static Foo theFoo;
 return theFoo;
}

oder wenn's sein muss tu die Implementierung in den Header und schreib 
"inline" davor.

Was soll das "volatile"?
#6414033
Lesenswert?

Ungetestet

Info.hpp:
1
namespace bla{
2
  namespace blub{
3
    extern bool bIrgendwas; //Das ist nur eine Information, dass es IRGENDWO diese Variable gibt
4
  }
5
}

a1.cpp
1
#inclde "Info.hpp"
2

3
std::cout << bla::blub::bIrgendwas;

a2.cpp
1
bool bla::blub::bIrgendwas = true; //Das hier ist die tatsächliche Definition
Gast #6414488
Lesenswert?

Ok hatte es dann falsch verstanden...
Wenn man es über extern bekanntmacht, funktioniert es.

Das dieses Beispiel nicht sinnvoll ist mir klar. Mir ging es ums 
Verständnis und die Möglichkeit die Dateien aufzusplitten.
Danke.
Gast #6415369
Lesenswert?

@ WasSindSchonNamen

Grundsätzlich:
*************
Die Definition der namespaces gehört doch eigentlich in die *.h(pp) 
Dateien und die namespaces werden dann in den *.c(pp) Dateien - nachdem 
die entsprechenden *.h(pp) Dateien inkludiert sind - global mit using 
namespace xx; oder lokal mit xx::foo(); eingebunden.
Gast #6415421
Lesenswert?

A. B. schrieb:
> Grundsätzlich:
> *************
> Die Definition der namespaces gehört doch eigentlich in die *.h(pp)
> Dateien und die namespaces werden dann in den *.c(pp) Dateien - nachdem
> die entsprechenden *.h(pp) Dateien inkludiert sind - global mit using
> namespace xx; oder lokal mit xx::foo(); eingebunden.

Ganz sicher nicht! Warum sollte man das machen? Man wirft mit using 
namespace jeden Vorteil der namespaces aus dem Fenster.
Gast #6415621
Lesenswert?

mh schrieb:
> Ganz sicher nicht! Warum sollte man das machen? Man wirft mit using
> namespace jeden Vorteil der namespaces aus dem Fenster.

Du kannst das gerne so machen wie du es für richtig hältst.

Ich mag manchmal nicht x-mal für Standard-Funktionen std:: voranstellen 
und schreibe deshalb gerne: using namespace std;

Dasselbe gilt für hardwarenahe Libraries, die in namespaces gekapselt 
sind. Für die konkrete Anwendung ist die Hardware ja dann bekannt und 
using namespace HARDWARE; stellt dann Klassen, Funktionen, Variablen, 
ect ..  für diese Platform zur Verfügung, ohne dass man immer HARDWARE:: 
voranstellen muss.
Gast #6416400
Lesenswert?

Sven B. schrieb:
> Oliver S. schrieb:
>> Sven B. schrieb:
>>> Ein normales C++-Programm braucht das extern-Keyword genau 0
>>> mal.
>>
>> Oder auch öfter.
>
> Wofür bitte?

Kommentare braucht es eigentlich auch nicht - man kann sie aber 
schreiben, um irgendetwas zu vermitteln. Für globale Variablen braucht 
man das natürlich nicht, denn die gibt es ja in C++ Programmen nicht.
#6416663
Lesenswert?

Al Fine schrieb:
> Für globale Variablen braucht man das natürlich nicht, denn die gibt es ja in
> C++ Programmen nicht.

Stimmt, die meisten missbrauchen dafür lieber ein Singleton, das dann im 
Wesentlichen die gleichen Nachteile hat, aber man kann sich ein extern 
sparen.

Sven B. schrieb:
> In welchem Fall braucht man für eine globale Variable das "extern"
> Keyword?

In dem Fall, dass man sie irgendwo nur deklarieren will - halt wie in C.
Was mich auch gleich auf eine andere Verwendung von extern bringt, 
nämlich das Einbinden von in anderen Sprachen wie z.B. C geschriebenem 
Code (extern "C").
#6417721
Lesenswert?

Rolf M. schrieb:
> In dem Fall, dass man sie irgendwo nur deklarieren will - halt wie in C.

Warum dann nicht eine Funktion mit einem lokalen static?

Foo& getGlobalFoo() {
  static Foo f;
  return f;
}

Der große Vorteil davon ist, dass es das "static initialization order 
fiasco" gleich mit vermeidet und zusätzlich Resourcen nur dann 
initialisiert, wenn sie auch gebraucht werden ...
Gast #6417905
Lesenswert?

Sven B. schrieb:
> Warum dann nicht eine Funktion mit einem lokalen static?

Wenn man nach dem "Warum?" fragt kann die Antwort auch "Bahnhof" sein. 
Sind wir hier im Kindergarten nach dem Motto "Wer? Wie? Was? ..."?
Ist nämlich schon richtig... - mach das als Funktion.

Wenn du in die Welt des Kaputten einsteigen willst, befasse dich mal 
genauer mit der C++ ABI und interop mit verschiedenen anderen Sprachen.
Was geht, was nicht geht, was faktisch nicht geht, aber theoretisch, was 
theoretisch nicht, aber dafür faktisch.
Es ist ein tiefer, dunkler Wald in dem Zwei plus Zwei Fünf ist und der 
Weg, der hinaus führt, nur breit genug für einen. Und der heißt nicht 
"modernes C++"....
Gast #6417921
Lesenswert?

Ja, also ich finde, man kann halt nicht vernünftig entwickeln, wenn auf 
alle Features verzichten muss. Andererseits ist die Sache da echt so 
gestrickt, dass man jede einzelne Nutzung absehbar bereuen wird, wenn 
sich der Scope der Anwendung erweitert. Was soll man da sagen? "Denk 
nicht an morgen"?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren