OOP + Globale Variablen
-
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
-
Sorry

Haste Recht,..Das Problem ist dass ich nicht weis wie ich die Adresse(!) zuweisen kann,... ?
Mittels pointer ok,..
Nur&ActivePic = Active;
Ergibt
[BCC32 Fehler] main.h(184): E2277 L-Wert erwartet
-
einfach
ActivePic = Active;Belies dich mal über Referenzen.
http://tutorial.schornboeck.net/referenzen.htm
-
So jetzt bin ichs nochmal,..
Irgendwie hab ich einen Knoten...Also,
Vorgehensweise:- Ich habe im TForm1 ein Objekt initalisiert,
public: // User declarations __fastcall TForm1(TComponent* Owner); Picture *ActivePic;- Ich übergebe beim erzeugen eines neuen Objekt dieses
Picture *pic = new Picture(OpenDialog1->FileName,ActivePic);- In meinem Objekt sage ich:
Picture(AnsiString dir,Picture* &pic){ ActivePic = pic; //und Window->OnActivate=aktiv;//Beim anklicken meiner erzeugten Form- Beim anklicken wird:
void __fastcall aktiv(TObject *Sender) { ActivePic = this; }Das heist bei einem anklicken wird ActivePic auf das momentane objekt gerichtet,..
Mein Fehler momentan ist dass ich nun über ActivePic->Window bzw. ActivePic->Image
auf die Eigenschaften und Methoden zugreife um das Bild bzw. das Fenster zu manipulieren.
z.b. zum invertierenvoid Invert(){ Graphics::TBitmap *bmp = ActivePic->Image->Picture->Bitmap; for(int y=0;y<bmp->Height;y++) { RGB *zeile = (RGB*) bmp->ScanLine[y]; //Width*3 for(int x=0; x < bmp->Width; x++) { zeile[x].R=~(zeile[x].R); zeile[x].B=~(zeile[x].B); zeile[x].G=~(zeile[x].G); } } ActivePic->Image->Picture->Bitmap=bmp; }Beim debuggen erzeugt es mir die Form und das Image und läd auch ein Bild rein, möchte ich nun Invertieren wird ein exception ausgelöst da
ActivePic nur "???" enthält,...
-
Hallo
Der Fehler wird schon durch diesen Bezeichnungsfehler hier deutlich
- Ich habe im TForm1 ein Objekt initalisiert,
C/C++ Code: public: // User declarations __fastcall TForm1(TComponent* Owner); Picture *ActivePic;Denn hier wird nicht ein Objekt initialisiert, sondern ein Pointer deklariert!
Es wird (laut dem Coedeauszug) nirgends eine echte Instanz der Klasse angelegt, der Pointer ActivePic bleibt uninitialisiert.
Das erklärt dann auch die Exception, denn du greifst dann über ActivePic auf ungültigen Speicher zu.Grundlagen in C++ und Speicherverwaltung wären hier sehr hilfreich.
bis bald
akari
-
Sorry hab ich vergessen zu posten:
void __fastcall TForm1::FormCreate(TObject *Sender) { ActivePic = new Picture(ActivePic); }bzw.
Picture(Picture* &Active){ ActivePic = Active; Window = new TForm(Application); Image = new TImage(Window); bar = new TStatusBar(Window); }Also ist schon wie geschrieben initalisiert !
-
Was soll denn das hier sein?
ActivePic = new Picture(ActivePic);eher so
ActivePic = new Picture(this);
-
Habe es nun umgewandelt,
der Grundkonstruktor erzeugt mir meine Grundobjekte,...public: Picture *ActivePic; Picture(TComponent* AOwner,Picture *pic) { Window = new TForm(Application); Image = new TImage(Window); bar = new TStatusBar(Window); ActivePic = pic; pic=this; v=0; }ActivePic = new Picture(this,NULL); Picture *pic = new Picture(this,ActivePic); pic->ActivePic=ActivePic; pic->LoadPicture(OpenDialog1->FileName); ActivePic->Window->Close();Demzufolge müsste durch den den "Close()" das gerade geöffnete Window geschlossen werden,.. leider stimmen die Adressen nicht überein ?
Ich weis mittlerweile wirklich nicht mehr weiter !?
-
Hier die endgültige Version die nun E N D L I C H
funktioniert!Folgendes war zu tun:
TForm1Picture *Active;deklariert !
Beim erstellen eines Objekts:
Picture *pic = new Picture(); pic->LoadFromFile(OpenDialog1->FileName); pic->SetActivePic(&Active);Konstruktor bzw. SetActivePic
Picture *ActivePic; Picture **pAdresse; Picture(){ Window = new TForm(Application); Image = new TImage(Window); Window->OnActivate=SetActive; } void SetActivePic(Picture* *pActive){ pAdresse=pActive; SetActive(NULL); }und bei jedem Mausklick auf das Window
void __fastcall SetActive(TObject *Sender){ if(pAdresse != NULL) *pAdresse=this; }Somit enthält das Picture *Active immer das momentan aktive Objekt
