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
namespaceb{
5
volatileboolvar;
6
7
namespaceb1{
8
boolget(){
9
returnb::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
namespacea{
3
volatileboolvar;
4
namespacea1{
5
boolget();
6
}// namespace a1
7
//usw...
8
}// namespace a
a1.cpp
1
//Bsp2
2
namespacea{
3
namespacea1{
4
boolget(){
5
returna::var;
6
}
7
//usw...
8
}// namespace aa
9
}
Kann es so überhaupt so umgesetzt werden wie ich es mir vorstelle?
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"?
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.
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 😁
@ 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.
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.
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
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.
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 ...
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
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++"....
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 ...
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"?