c++ In übergeordneten Namespace auf variable zugreifen

Gast #6413985
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
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.
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"?
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
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
@ 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
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
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
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.
Al Fine schrieb:
> 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.

In welchem Fall braucht man für eine globale Variable das "extern" 
Keyword?
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").
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
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
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

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.