Registriert: Mo Dez 26, 2005 22:27 Beiträge: 117
Programmiersprache: Pascal, C++
Hi allerseits, ich bin dabei meine GUI zu überarbeiten und bin auf folgendes Problem gestoßen:
Ich möchte aus speichertechnischen Gründen (wenn nichts anders angegeben) auf die in meiner "übergordneten" Klasse erstellten Displaylisten zugreifen, bzw auf die Funktion die mir dort den Text zeichnet.
Also ungefähr so:
Code:
pogGui = class ( ... ) private BaseFont : glUInt; //Displayliste objects : array of pogStandardClass; public ... end;
in pogStandardclass ist die Funktion zum Textausgeben so definiert:
Code:
procedure pogStandardClass.PrintText ( x,y: integer; text: string ) ; begin if (text = '') then exit;
if ParentFont then PpogGui ( Parent ) ^.PrintText(x,y,text) else begin glPushAttrib(GL_LIST_BIT); glRasterPos2i(x, y); glListBase(FontBase); glCallLists(Length(text), GL_UNSIGNED_BYTE, PChar(text)); glPopAttrib; end;
end;
In der Hauptklasse ist ParentFont natürlich false gesetzt. Wenn ich PrintText aus dieser Hauptklasse aufrufe gehts auch hervoragend
So hier mein Problem: In Parent speicher ich einen Zeiger auf meine Hauptklasse, sprich ich initalisiere meine Objekte so:
Code:
objects[i] := MeinObejct[i].Create( @self )
wobei self dann natürlich in Parent gespeichert wird. Problem ist: wenn ich nun aus einer "untergeordneten" Klasse PrintText aufrufe sollte er mir nun eigentlich die PrintText Funktion aus der Hauptklasse aufrufen... Tut er aber nicht - es passiert gar nix -.- Ich bekomme keinen Fehler, gar nix, gezeichnet wird a nix
Edit: Also er ruft die Procedure doch auf, sagt der debugger - aber gezeichnet wird trotzdem nichts.. zerstöre ich irgendwie die Displayliste oder rufe sie falsch auf?
Habt ihr eine Idee?
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
@Self kommt mir falsch vor … Sourcecode von der Methode, in der du die Zeile mit @Self stehen hast sowie dem Konstruktor, den du da aufrufst (den du eventuell auch falsch aufrufst, denn Konstruktoren müssen immer Typname.Create aufgerufen werden, mit sehr sehr wenigen Ausnahmen) wäre ganz gut.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Du arbeitest mit Objekten und so, da brauchst du @ eher nicht. @ erzeugt zwar einen Pointer, wo du auch komplett richtig gedacht hast, dass du das brauchst, aber Objektvariablen sind in Pascal immer schon Pointer. Was du mit @Self erzeugst ist also ein Pointer auf einen Pointer. Wenn du da mit dem dereferenzieren nicht genau aufpasst, bekommst du die falschen daten und wahrscheinlich auch den falschen Wert für die Displayliste. Als Parent nimmst du dann also am besten den Typ pogGui, sodass du direkten und richtigen Zugriff hast.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Sa Mär 14, 2009 17:48 Beiträge: 99
Programmiersprache: D, Java, C++
Sagmal haben Pointer in Delphi immer nur den Typ "Pointer" also sind im Endeffekt Typlos? Gibt es nicht sowas wie "Pointer auf Typ xxx"? Das würde solche Fehler verhindern.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Es gibt typisierte Pointer. Du kannst mit folgendem Code einen typisierten Pointer definieren.
Code:
type PBlah = ^TBlah;
Von welchem Typen TBlah ist, ist egal. Das kann ein record, ein Array, eine Integer oder sonst etwas sein. Es gibt auch schon viele vordefinierte Pointertypen. PChar, PByte, PInteger etc. ABER. Pointer bleiben Zuweisungskompatibel. Also ein PByte kann problemlos auf ein Pointer oder ein PInteger zugewiesen werden. Was auch logisch ist, da ein Pointer nur eine Speicheradresse enthält. Und der Adresse ist es egal ob der Speicher als Integer, Byte oder als Record benutzt wird.
Zum Thema Klassen. Es macht nur sehr sehr selten Sinn einen Pointer auf eine Klasse oder einen Pointer auf einen Pointer zu benutzen. Der Grund dafür ist folgender. Wenn du einen Pointer eines Pointers erfragst, dann erfragst du in Wirklichkeit die Adresse der Variable in der der Pointer gespeichert ist. Ist diese Variable nur eine lokale Variable innerhalb einer Methode, dann ist diese nur Gültig so lange man sich in der Methode befindet. Wird die Methode verlassen, dann kann die Stelle auf die unser Pointer zeigt wieder überschrieben werden. Und dabei spielt es keine Rolle ob wir einen Pointer einer Klasse, eines anderen Pointers oder eines LongStrings haben wollen. Im übrigen weiß ich nicht was man bei @self bekommt.
Bei den Klassen ist es also absolut nicht nötig irgendwas mit Pointer drehen zu wollen. Ich vermute auch mal, dass es dadurch zu diesem Problem kommt. Ich würde da direkt die Klasse übergeben. Wobei das aber darauf ankommt wie deine Struktur aussieht. Von daher kann ich nicht abschätzen ob deine Klasse pogStandardClass die Klasse pogGui bereits kennt. Bzw was du machen müsstest damit das so wäre. Denn dann könntest du folgendes machen. Damit wärst du was den Typen angeht auf jeden Fall auf der sicheren Seite. Aber wie gesagt. Kommt auf deine Struktur an.
Registriert: Mo Dez 26, 2005 22:27 Beiträge: 117
Programmiersprache: Pascal, C++
Ich hatte zuerst auch gedacht dass ich statt einen typlosen Pointer einen spezifizierten nehme - Problem ist: pogStandardclass kennt keine anderen Klassen, da sich alle anderen von ihr ableiten.
Aber der Hinweis dass self bereits ein Pointer ist hat geholfen. Ich übergeb jetzt einfach self statt @self und derefernziere jetzt auch richtig ud siehe da: Es geht Pointer aud Pointer macht hier auch wirklich keinen Sinn. Intressant ist nur warum er mir keinen Zugriffserror gebracht hat ^^
Danke an euch
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Meiner Meinung nach solltest du dennoch einen Weg suchen um deine Klassen vernünftig weiter zu reichen. Also ohne das über Pointer machen zu müssen. Dass die sich gegeneseitig nicht kennen glaube ich gerne. Klassisches Problem. Bzw da eine Struktur zu erschaffen, mit der es geht, ist die hohe Kunst des OOPs.
Registriert: Mo Dez 26, 2005 22:27 Beiträge: 117
Programmiersprache: Pascal, C++
@Sascha und Lossy:
Okay Forward-Deklarationen sind eine Möglichkeit, aber im Endeffekt reiche ich trotzdem Pointer durch? Meiner Meinung nach ist es unmöglich sowas ohne Pointer zu machen.. Natürlich sieht es OOP-technisch schöner aus was Sascha geschrieben hat ( so ähnlich habe ich es auch jetzt implementiert ) aber im grunde unterscheidet es sich nicht von dem was am Anfang hatte, da Objektvariablen ja sowieso schon Pointer sind.
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Ich versuche generell zu vermeiden, dass Kindobjekte auf ihre Eltern zugreifen können. Es hat natürlich in gewissen Situationen auch einen Sinn das so umzusetzen -keine Frage- .
Ich kenne jetzt den kompletten Zusammenhang nicht. Frage ist: Muss ein Teil einer GUI überhaupt dazu in der Lage sein an einem übergeordneten Teil der GUI etwas zu ändern? Man könnte die beiden Teile auch in ein neues GUI Element kapseln.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Carmageddon: Technisch gesehen hast du recht. Für die CPU ist es egal ob du das Objekt als Klasse durchreichst oder als Pointer. Und natürlich sind alles Pointer. Deswegen ganz ohne gehts nie. Für den Kompiler ist das aber nicht egal. Wenn du die Instanz als Pointer druchreichst und später castest, dann kommt wieder das gleiche raus was du rein gesteckt hast. Das ja. Allerdings verzichtest du dann auf ein ganzes Stück Typprüfung. Du könntest dich beim Schreiben vertun und sonstwas für einen Pointer dort übergeben, einen Pointer auf eine Instanz einer ganz anderen Klasse oder du könntest es auch falsch casten. Wenn du nur mit Klasseninstanzen arbeiten würdest, dann würde dir der Kompiler beim Übersetzen bereits einen Fehler anmeckern. Mit Pointern merkst du es nur, wenn dein Programm zur Laufzeit etwas versucht was nicht geht. Weil es dann unkontrollierte Zugriffsverletzungen gibt. Es gibt aber auch bei Klassen verschiedene Möglichkeiten die Typprüfung zu umgehen. So ist es nun auch nicht.
Im Endeffekt waren das nur Hinweise/Empfehlungen. Wie du es letzten Endes machst ist deine Entscheidung. Und ehrlich gesagt ist mir persönlich das auch ziemlich egal.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
damadmax hat geschrieben:
Muss ein Teil einer GUI überhaupt dazu in der Lage sein an einem übergeordneten Teil der GUI etwas zu ändern?
Sowas kommt vor. Zum Beispiel: der Benutzer klickt auf ein MenuItem, und das Menuitem signalisiert seinem Root-Menu nach getaner Arbeit, dass jetzt der ganze Tree-Branch jetzt geschlossen werden kann.
Muss ein Teil einer GUI überhaupt dazu in der Lage sein an einem übergeordneten Teil der GUI etwas zu ändern?
Sowas kommt vor. Zum Beispiel: der Benutzer klickt auf ein MenuItem, und das Menuitem signalisiert seinem Root-Menu nach getaner Arbeit, dass jetzt der ganze Tree-Branch jetzt geschlossen werden kann.
Hier MACHT das Menuitem aber nichts mit dem Parent und muss diesen auch nicht kennen. Es sagt nur: "Bin fertig und alles schick". Und die übergeordnete Strukur kann dann entscheiden, was nun getan werden sollte. Halt sich auch schließen (Menu) oder einen Kuchen backen...
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.