OOP + Globale Variablen
-
Hallo
Das sind ja dann auch keine globalen Variablen mehr. Warum kannst du denn eigentlich nicht auf globale Variablen zugreifen? Was kommt da für eine Fehler?
chrische
-
[BCC32 Fehler] main.h(57): E2231 Element TForm1::test kann nicht ohne ein Objekt verwendet werden
class TForm1 : public TForm { public: // User declarations __fastcall TForm1(TComponent* Owner); TForm *ActiveForm; TImage *ActiveImage; AnsiString SavePath; int test; class Picture{ private: void __fastcall aktiv(TObject *Sender) { test=10; }....
-
Hallo
Das ist doch auch keine globale Variable, sondern ein Member von TForm1.
int test; class TForm1 : public TForm { public: // User declarations __fastcall TForm1(TComponent* Owner); TForm *ActiveForm; TImage *ActiveImage; AnsiString SavePath; class Picture{ private: void __fastcall aktiv(TObject *Sender) { test=10; }....Das ist hässlich, aber dürfte funktionieren.
chrische
-
Stimmt,...
Doch dann kann ich aus einer anderen Form nicht mehr auf die (jetzt,.. wirklich globale Variable zugreifen!)Gibt es keinen Weg von meiner unterklasse picture auf die oberklasse TForm zuzugreifen ?
-
Woher soll die Unterklasse denn wissen, auf welchen Objektes Variablen sie zugreifen soll? Du mußt ihr schon eines übergeben.
-
Hallo
Du könntest die globale Variable in eine Datei schreiben, die von allen Datein inkludiert wird. Du könntest aber der Klasse picture auch einfach eine Variabel im Konstruktor mitgeben:
TForm1 -> member int test = 01; Picture -> member int _test; c'tor: public Picture(int test) { _test = test; }chrische
-
audacia schrieb:
Woher soll die Unterklasse denn wissen, auf welchen Objektes Variablen sie zugreifen soll? Du mußt ihr schon eines übergeben.
Form1->test
funktioneirt ja leider auch nicht

Danke für die Vorschläge aber !
-
Hallo
Übergib' der Klasse doch Picture doch einfach im Konstruktor den Wert den es bekommen soll. Genauso, wie ich es geschrieben habe. Wenn es dabei Probleme gibt, dann helfen wir dir sehr gerne.
chrische
-
Konstruktor
Picture(AnsiString dir,TForm *ActiveForm){und die Funktion
private: void __fastcall aktiv(TObject *Sender) { ActiveForm=Window; }Würde mir meine Logik nun sagen, der Compiler widerspricht mir leider

undef. Symbol...
-
Hallo
Was ist Window und was machst du im Konstruktor mit den Parametern?
chrische
-
Hier alles...
class Picture{ private: void __fastcall aktiv(TObject *Sender) { ActiveForm=Window; } public: TForm *Window; TImage *Image; TStatusBar *bar; int m_Width; int m_Height; __property int Height ={read=m_Height}; __property int Width ={read=m_Width}; //-------------------------------------------->>>>>> Picture(AnsiString dir,TForm *ActiveForm){ Window = new TForm(Application); Image = new TImage(Window); bar = new TStatusBar(Window); Image->Picture->LoadFromFile(dir); Image->AutoSize=true; Image->Width=Image->Picture->Width; Image->Height=Image->Picture->Height; Image->Align=alClient; Image->Parent=Window; Window->Caption=ExtractFileName(dir); Window->BorderStyle=bsToolWindow; Window->Width = Image->Picture->Width; Window->Height = Image->Picture->Height; Window->Position=poMainFormCenter; Window->OnActivate=aktiv; m_Width=Window->Width; m_Height=Window->Height; bar->SimpleText=IntToStr(Width)+" x "+IntToStr(Height); bar->SimplePanel=true; bar->Parent=Window; Window->Show(); } //-------------------------------------------->>>>>> ~Picture(){ delete bar; delete Image; delete Window; } };Window ist dass durch die Klasse erzeugte neue Form,..
-
Hallo
Zuerst solltest du deine Membervariablen private machen, vor allem, wenn du dann noch Properties dafür schreibst. Der zweite Punkt ist der, dass du nun eine Variable an den Konstruktor übergibst, aber gar nichts damit machst. Du solltest dir vielleicht noch einmal die Grundlagen von OOP reinziehen.
chrische
-
Die Frage ist wohl eher wie ich meinen Übergebene Wert an die Funktion übergebe, da ich bei
Window->OnActivate=aktiv;Keine Variablen übergeben darf,...
-
Hallo
Ich kenne mich mit VCL nicht aus, aber was du machst, ist Quatsch. Du übergibst den Konstruktor einen Parameter und lässt diesen links liegen.
chrische
-
Global nun richtig:
TForm *ActiveForm;
TImage *ActiveImage;void __fastcall aktiv(TObject *Sender) { ActiveForm = Window; ActiveImage = Image; }Funktioniert nun

Lediglich das Zugreifen auf die MEthoden von TForm bzw. TImage der beiden funktioniet nicht
Der Debugger z.B. liest schön und gut die richtige Caption raus, verändere ich diese und quittiere ich die änderung mit einem
ActiveForm->Update();
Kommt eine FEhlermeldungZugrissverletzung bei Adresse 20139079 in Modul vcl100.bpl
Lesen von Adresse 0000 004C nicht möglich...
Find ich skuril!
-
Wie chrische5 schon sagte, wenn du einen passenden Parameter im Konstruktor hats, verwende ihn auch. da du hier einen Pointer ändern willst musst du ihn natürlich als Referenz übergeben.
Picture(AnsiString dir,TForm*& activeForm, TImage*& activeImage) { // Deine Initialisierung activeForm = Window; activeImage = Image;
-
Es funktioniert nun ja...
Eine "active"-Klasse von meiner klasse initlisieren und das global,..
funktioniert prächtig,..In der Form1 (main.cpp) kann ich nun per
ActivePic->Window->Caption="Test";Jederzeit auf das zuletzt aktive Element zugreifen,...
Soweitsogut,..Wenn ich nun in der Form2 das selbe machen möchte 1:1,..
Bekomm ich den fehler, OBWOHL die Adresse der beiden Elemente gleich ist ?
-
christianz schrieb:
...
Du solltest dir wirklich erst einmal die Grundlagen der Objektorientierten Programmierung aneignen. Zudem sind globale Variablen mit ganz wenigen Ausnahmen (und selbst die kann man meistens Vermeiden) weder gute Programmierung noch ohne Probleme...
Punkt 1: Klasse vs. Objekt
Eine Klasse ist eine abstrakte Beschreibung, Objekte sind konkrete Instanzen von den Klassen. Jede Instanz (= Objekt) belegt einen eigenen Speicherbereich.Punkt 2: Datenkapselung & Wartbarkeit
Ein Objekt sollte möglichst Eigenständig für sich arbeiten. Es ist nicht verboten es aus mehreren Teilen (Objekten) aufzubauen, aber diese sollten Teil des Ganzen sein. Alles was ein Objekt von Außen benötigt sollte über seine Schnittstelle übergeben werden. Alles was Teil des Objektes ist, sollte ebenso nur über wohldefinierte Schnittstellen bereitgestellt werden, und das auch nur wenn es sinnvoll ist (private Member, ggf. Setter/Getter...).Wenn du dir einen DVD-Spieler anschaust, wirst du auch nicht ohne Gewalt an seinen "Innereien" rumspielen können, und er besitzt nach außen hin eine saubere Schnittstelle über die du mit ihm interagierst. Wenn du eine DVD anschauen willst, machst du dies über die Schnittstelle.
Vereinfacht gesprochen:
dvdspieler.Open(); dvdspieler.SetDVD(const DVD& dvd); dvdspieler.Play();Der DVD spieler hält dabei die DVD (= Membervariable, wird im SetDVD gesetzt)...
Die Fernbedienung greift nun auch nicht global auf den dvdspieler zu. Wenn die Fernbedienung erstellt wird (Konstruktor) wird sie auf den DVD-Spieler eingestellt (z.B. Parameter des Konstruktors).
So dies als kurze Einführung. Grundsätzlich solltest du dir merken:
Definiere immer so lokal wie möglich, aber so global wie nötig.Ist dein Aktives Bild nun Applikationsglobal, oder ist es z.B. Teil des Fensters...
cu André
-
Kurze Frage noch,...
Habe es nach euren Ratschlägen umstrukturiert,
Bin momentan soweit dass ich ein Objekt (!) "ActivePic" übergebe und dies anschließend per this zuweise,..
Somit ist ActivePic immer das zuletzt erzeugt Bild,..
Funktioniert auch,..
nun habe ich intern auch ein "ActivePic" dem möchte ich die gleiche Adresse wie dem public ActivePic zuweisen,..private: Picture* ActivePic; Picture(AnsiString dir,Picture* &Active){ Active = this; ActivePic = Active;Nur die Zuweisung funktioniert nicht da ich ja die Adresse zuweisen will,..
ein
*ActivePic = Active;Funktioniert aber auch nicht ?
-
Hallo
Versuch' dir doch mal anzugewöhnen, dass "geht nicht" nichts aussagt. Sollen wir jetzt raten, wo das Problem ist? Zeig also immer noch die Fehlermeldung oder beschreibe das vermeintliche Fehlverhalten.
chrische