Globale Variablen werden nicht erkannt
-
ich versteh das mit diesen scopes noch immer nicht.
ich hab eine main.cpp und mehrere .h dateien. ich will in den h dateien auf elemente aus der main.cpp zugreifen, aber die werden in der .h datei einfach nicht erkannt, obwohl sie global sind also außerhalb einer funktion.
hab dann noch versucht eine andere .h datei zu machen wo die wichtigen elemente enthalten sind, aber darauf kann ich dann auch nicht zugreifen.
also wie geht das?
-
Das sind Grundlagen. Also, so banal sich das auch anhören mag, hol dir ein Buch und lern die Grundlagen. Nur wenn du sie richtig verstehst, kannst du sinnvoll weitermachen.
Warum willst du aus einer Header Datei auf Sachen aus der cpp Datei zugreifen? Macht keinen Sinn. Natürlich sind sie in der Header nicht bekannt.
-
Der Header kann doch nicht die Variablen aus der main.ccp kennen, selbst wenn die Variablen global deklariert sind. Die Header weiß nicht einmal das eine Datei mit dem Namen main.cpp existiert.
Wenn du aber eine Headerdatei in deine main.cpp einbindest kannst du aus der main.cpp auf globale Variablen der Headerdatei zugreifen.
-
dann können die klassen die ich in einer header datei erstelle wohl auch nur auf die sachen zugreifen die in ihrer eigenen datei sind oder nicht?
und ich hab schon über 800 seiten aus einem c++ buch gelesen, das müsste die grundlagen ziemlich gut abgedeckt haben.
-
Nikolai schrieb:
dann können die klassen die ich in einer header datei erstelle wohl auch nur auf die sachen zugreifen die in ihrer eigenen datei sind oder nicht?
Nein, der Code dazu sollte nämlich ganz woanders stehen und dort sind dann auch sicher die passenden Deklarationen vorhanden.
und ich hab schon über 800 seiten aus einem c++ buch gelesen, das müsste die grundlagen ziemlich gut abgedeckt haben.
Kommt auf das Buch an. Leider sind ein paar sehr populäre Bücher (C++ von A-Z, C++ für Dummies, C++ in 21 Tagen, alles mit C/C++ im Titel, alles von Jürgen Wolf, fast alles vom Galileo-Verlag) absoluter Müll.
-
1 cpp-Datei ist 1 Übersetzungseinheit. Eine Übersetzungseinheit kennt nur das, was in ihr steht. Eine Header-Datei ist keine Übersetzungseinheit. Eine Header-Datei kann aber einer Übersetzungseinheit hinzugefügt werden, mittels
#include. Der Preprocessor ersetzt dann die#include-Directive mit dem Inhalt der Header-Datei. Der Compiler bekommt also von einer Header-Datei überhaupt gar nichts mit.
-
extern istNichtSoSchoenWieDependencyInjection;
-
ich hab übrigens das buch genommen, war aber irgendwann ziemlich frustrierend wenn die lösungen der übungen ganz anders waren als ich es gemacht hab...
-
Microsoft Visual C++ 2010
Vergiss IDEs, hol dir einen vernünftigen Compiler (GCC), dazu einen brauchbaren, simplen Texteditor (vim, gedit) und dazu ein System, das du als Programmierer überblicken kannst (Fedora, Gentoo), damit du auch sicher weißt, was du tust.
-
Ki schrieb:
Microsoft Visual C++ 2010
Vergiss IDEs, hol dir einen vernünftigen Compiler (GCC), dazu einen brauchbaren, simplen Texteditor (vim, gedit) und dazu ein System, das du als Programmierer überblicken kannst (Fedora, Gentoo), damit du auch sicher weißt, was du tust.
... führe damit zwei Hallo-Welt-Programme aus, einfach um mal zu sehen was man da alles machen muss und kehre dann wieder zurück zu einer der produktivsten IDEs, nämlich Visual Studio.
-
Ki schrieb:
Vergiss IDEs, hol dir einen vernünftigen Compiler (GCC), dazu einen brauchbaren, simplen Texteditor (vim, gedit) und dazu ein System, das du als Programmierer überblicken kannst (Fedora, Gentoo), damit du auch sicher weißt, was du tust.
Klar, wenn man mit dem Programmieren nicht klar kommt, sollte man sich noch zusätzliche Hürden in den Weg legen. Lass ihn doch erst mal seinen eigenen Prozessor zusammenlöten

OP: Deine Frage wurde zwar schon beantwortet, aber IMHO nicht auf einem anfängerfreundlichen Niveau. Damit dem Compiler eine (globale) Variable bekannt ist, muss sie vorher, d.h. weiter oben im Quelltext, deklariert worden sein.
Welche Dateien übersetzt dein Compiler? Jede cpp-Datei bildet eine sogenannte Übersetzungseinheit, die sich der Compiler dann anschaut. Die h-Dateien werden nur jeweils genau dann kompiliert, wenn sie in einer Übersetzungseinheit inkludiert werden. Inkludieren heißt nichts anderes als reine Textersetzung. Wo also
#include "foo.h"steht, könntest du genauso gut den Inhalt von foo.h hinschreiben.Wo stehen die include-Anweisungen? In aller Regel am Anfang einer Datei. Davon solltest du auch nicht abweichen. Wenn du also in der main.cpp oben foo.h inkludierst und weiter unten eine globale Variable deklarierst, die foo.h braucht, kann das nicht funktionieren: Der Compiler ersetzt die include-Anweisung durch den Quellcode aus foo.h, der die globale Variable braucht, d.h. dieser Code steht vor der Deklaration der globalen Variable. Das führt dann natürlich zu einem Fehler.
Komm jetzt nicht auf die Idee und deklariere die globale Variable vor der include-Anweisung. Damit kommst du nur in Teufels Küche. Überlege dir stattdessen, dass du die globale Variable gar nicht benötigst. Du könntest beispielsweise den Funktionen aus foo.h, die die Variable benötigen, einen entsprechenden Parameter verpassen.
-
und was ist wenn ich mehrere cpp dateien habe? da werden die elemente der einen in der anderen auch nicht erkannt. ich hab eine klasse und ein array mit zeigern auf objekte dieser klasse. wenn ich das objekt sich selbst aus dem array entfernen lassen will muss ich ja auf das array zugreifen, soll ich das dann jedes mal im konstruktor übergeben oder geht das auch anders?
-
1. Globale Variablen sind abenteuerlich, besser sein lassen.
2. Arrays sind abenteuerlich, besser sein lassen, Containerklassen benutzen
3. Zeiger sind auch abenteuerlich. Sicher, dass du sie brauchst? (Tipp: Höchstwahrscheinlich nicht)
4. Arrays von Zeigern sind somit doppelt abenteuerlich.
5. Globale Arrays aus Zeigern sind somit das fehleranfälligste, was irgendwie möglich ist.
6.wenn ich das objekt sich selbst aus dem array entfernen lassen will
Auch ein abentuererliches Vorhaben. Beschreib lieber mal, was du erreichen möchtest, nicht wie du dir die technische Lösung vorstellst. Die technische Lösung ist bei dir nämlich von deinem mangelndem Verständnis geprägt und von den abenteuerlichen Techniken, die du in dem Buch beigebracht bekommen hast.
Mit diesen Hinweisen nun die Antwort auf deine Frage, die du dann hoffentlich nicht benutzt, weil dir die Hinweise zu Herzen nimmst:
class_header.h
// Bei den Headern Includeguards nicht vergessen, schreibe ich aber nicht explizit hin class foo { // Bla };global_array_header.h
#include "class_header.h" // Eine forward-Definition würde hier auch reichen, da du nur Zeiger auf foo benutzt extern foo *array[1234];#include "global_array_header.h" #include "class_header.h" // Code der foos und das array benutztclass_implementation.cc:
#include "global_array_header.h" #include "class_header.h" // Code der foos und das array benutztglobal_array_implementation.cc
#include "class_header.h" foo *array[1234];
-
Nikolai schrieb:
...
Du hast selbst gesagt, das du bereits ein Buch gelesen hast, ich behaupte das darin auch auf die Trennung von Headern und Sourcedateien intensiv eingegangen wurden ist. Und dieses Thema solltest du dir nochmals intensiv zur Brust nehmen.
Prinzipiell: cpp-Dateien sollten niemals voneinander abhängig sein, Header dienen der Deklaration (und in der jeweiligen Source steht die Implementierung). Und dann inkludiert man diese Header wo sie benötigt werden ein.
Ganz davon abgesehen sind globale Variablen ohnehin nur in Ausnahmen sinnvoll.
-
was ich vorhabe ist, den server anfragen von clients annehmen zu lassen. dafür hab ich eine client klasse erstellt wo die infos wie der socket und die sockaddr infos drinne sind. hab jetzt versucht ein struct an den konstruktor übergeben zu lassen, nichtmal das funktioniert.
struct CltInfo{ int pos; SOCKET s; sockaddr addr; Client *** clients; int* cltcnt; };in der zeile mit Client *** clients; kommt der fehler
error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'clients'
vieleicht weil die klasse erst danach definiert wurde... und wenn ich die struktur erst danach definiere dann kommt fehler mit undefiniertem struct.
-
Nikolai schrieb:
error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'clients'
vieleicht weil die klasse erst danach definiert wurde...Sogar ganz sicher aus diesem Grund.
und wenn ich die struktur erst danach definiere dann kommt fehler mit undefiniertem struct.
Welcher genau?
Wie auch immer:
1. Hier reicht eine Forward-Declaration:class Client; struct CltInfo{ int pos; SOCKET s; sockaddr addr; Client *** clients; int* cltcnt; };Aber setz das nicht voreilig ein, denn:
2. Dein Code ist grauenhaft und wird bestimmt nur mit vielen Schmerzen zum Laufen gebracht werden. Du bist nämlich im wahrsten Sinne des Wortes ein Drei-Sterne-Programmierer:
Google: three star programmer
Abstraktion und klares Design helfen ungemein bei der Fehlervermeidung!
3. So wie es aussieht, hast du irgendeinen C/C++-Mischmasch gelernt. Damit wirst du Schwierigkeiten bekommen, besonders da dein Projekt durchaus anspruchsvoll zu sein scheint. Da ist saubere Programmierung in einer Sprache Pflicht, wenn du jemals zu einem brauchbaren Ergebnis kommen möchtest. Dazu müsstest du natürlich zuerst eine der Sprachen richtig lernen.
-
Michael E. schrieb:
Klar, wenn man mit dem Programmieren nicht klar kommt, sollte man sich noch zusätzliche Hürden in den Weg legen. Lass ihn doch erst mal seinen eigenen Prozessor zusammenlöten

Es geht nicht um Hürden, sondern um Verständnis

-
http://c2.com/cgi/wiki?YouMightBeaThreeStarProgrammer
@SeppJ: Genial. Leider traf nur eine einzige Sache zu:
Ich benutze wo möglich den Ternären Operator um If-Statements zu vermeiden.@Ki: Als Anfänger braucht man dein "Verständnis" nicht. Deswegen ist man ja auch "Anfänger", weil man es nicht versteht
Vor allem sollte man nicht versuchen, Anfänger mit komplexen Zeug zu verunsichern oder wegzuschrecken.