Forum: PC-Programmierung c++ In übergeordneten Namespace auf variable zugreifen


von WasSindSchonNamen (Gast)


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?

von mh (Gast)


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.

von Ben S. (bensch123)


Lesenswert?

Woher soll "a1.cpp" irgendwas über die Inhalte von "a.cpp" wissen? Du 
musst die Information über .hpp/.h Dateien weiterreichen.

: Bearbeitet durch User
von Sven B. (scummos)


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"?

von Ben S. (bensch123)


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

: Bearbeitet durch User
von WasSindSchonNamen (Gast)


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.

von Sven B. (scummos)


Lesenswert?

Das extern ist keine Lösung für welches Problem auch immer du lösen 
möchtest. Ein normales C++-Programm braucht das extern-Keyword genau 0 
mal.

von Al Fine (Gast)


Lesenswert?

Ben S. schrieb:
> Woher soll "a1.cpp" irgendwas über die Inhalte von "a.cpp" wissen?

Komisch: wenn es um ODR Verstöße geht, weiß der Compiler das.

von Ben S. (bensch123)


Lesenswert?

Sven B. schrieb:
> Das extern ist keine Lösung für welches Problem auch immer du lösen
> möchtest. Ein normales C++-Programm braucht das extern-Keyword genau 0
> mal.

Das stimmt, ist aber halt nicht das wonach gefragt wurde 😁

von A. B. (Gast)


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.

von mh (Gast)


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.

von Oliver S. (oliverso)


Lesenswert?

WasSindSchonNamen schrieb:
> Das dieses Beispiel nicht sinnvoll ist mir klar. Mir ging es ums
> Verständnis und die Möglichkeit die Dateien aufzusplitten.
> Danke.

Jetzt hast du zwar eine Lösung, nur fehlt dir dazu noch das passende 
Problem ;)

Sven B. schrieb:
> Ein normales C++-Programm braucht das extern-Keyword genau 0
> mal.

Oder auch öfter.

Oliver

von A. B. (Gast)


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.

von Sven B. (scummos)


Lesenswert?

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

Wofür bitte?

von Al Fine (Gast)


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.

von Sven B. (scummos)


Lesenswert?

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?

von Rolf M. (rmagnus)


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").

von Sven B. (scummos)


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 ...

von Oliver S. (oliverso)


Lesenswert?

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

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

Und wenn schon als Singleton, dann wenigstens komplett. Guggst du Scott 
Meyers.

Oliver

von Al Fine (Gast)


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++"....

von Sven B. (scummos)


Lesenswert?

Ich seh schon, wie immer bei C++ lebt hier jeder Teilnehmer des Threads 
in seiner eigenen kleinen C++-Blase, und davon will ich mich gar selbst 
nichtmal ausnehmen ...

von Al Fine (Gast)


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"?

von Heimlehrgangsprogrammierer (Gast)


Lesenswert?

Hier scheint die praktisch Seite gut erklärt zu sein:

http://www.cplusplus.com/doc/oldtutorial/namespaces/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.