![]() |
Delphi-Version: 5
Verwenden von Pointern
Hiho,
Ich habe da so ein winziges Problem. Ich habe beim onCreate von Form1 ein Objekt gebaut. Dieses wird am ende onDestroy auch wieder freigegeben. Nun möchte ich dieses eine Objekt Global in allen Forms verwenden. Dabei ist es wichtig, dass es das selbe Objekt ist und nicht ein neues der gleichen Art. Ich habe mir gedacht dass ich onCreate halt dieses Objekt erstelle, danach einen Pointer auf dieses setze und den Pointer an alle anderen Forms weitergebe, so dass ich in allen Forms mit dem selben Objekt arbeite. Jetzt habe ich direkt eine ganze Latte Probleme. - geht das überhaupt so wie ich mir das so vorstelle? - ich hab zwar schon einen Pointer-Guide durchgelesen, aber weis irgendwie trotzdem nicht, wie ich das schreiben sollte. - Kann ich die einzelnen Methoden des Objektes auch über den Pointer ansprechen (Pointername.Methode) oder muss ich mir irgendwie ein Objekt initialisieren und dem dann mein altes Objekt zuweisen, so dass ich mehrere Objekte initialisiert habe, aber im Grunde alle Objekte nur eines sind. (Nicht einfach zu erklären, was ich für einen Gedanken hatte...) Kann mir vielleicht jemand ein kleines Beispiel entwerfen, das ich dann analysieren kann? Das würde mich sehr freuen. Gruß Getox |
AW: Verwenden von Pointern
Vergiss Pointer hierfür ab besten gleich wieder. Die Variable, der du das Objekt bei der Erstellung zuweist ist bereits intern ein Pointer, der von Delphi aber etwas komfortabler als "Referenz" nutzbar gemacht wird.
Delphi-Quellcode:
foo und bar sind danach 2 Referenzen auf exakt das selbe Objekt.
var
foo, bar: TMyClass; begin foo := TMyClass.Create; bar := foo; end; Edit: Bei Records schaut die Welt wieder etwas anders (komplizierter) aus, aber wenn es wirklich und nur um Objekte geht, spielen "manuelle" Pointer keine Rolle. |
AW: Verwenden von Pointern
Hallo,
estelle Dir eine Unit mit der "globalen Klasse". Diese Unit kannst Du in alle Forms einbinden. Nutze das ![]()
Delphi-Quellcode:
Grüße
type
TDeineKlasse = class(TObject) private class var fInstance: TDeineKlasse; constructor create; public class function getInstance: TDeineKlasse; end; implementation class function TDeineKlasse.getInstance: TDeineKlasse; begin if not assigned(fInstande) then fInstance := TDeineKlasse.create; result := fInstance; end; Klaus |
AW: Verwenden von Pointern
Ein Objekt wird immer über einen Pointer angesprochen.
Wenn Du z.B. auf Panel1 zugreifst, wird auf eine Speicheradresse zugegriffen. Der entsprechende Speicherplatz auf den der Pointer verweist wird dann in als Klasse TPanel interpretiert. Insofern kannst Du Deine Instanz Panel1 anderen Units zugänglich machen und musst nicht extra mit Pointern hantieren. Wenn Du der Unit uForm2 Deine Unit uForm1 bekannt gibst, kannst Du auf Form1.Panel1 ganz normal zugreifen. Du könntest aber auch eine globale Unit definieren, in der Du eine entsprechende Objektvariable definierst. Im OnCreate Deines Hautpformulars weist Du dieser dann Deine Objektinstanz zu und im OnDestroy setzt Du sie auf nil. Dann kannst Du von den anderen Formularen aus auf diese globale Variable zugreifen. Im Grunde läuft es darauf raus, dass Du eine Variable von verschiedenen Stellen aus zugängliche Variable definierst, der dann irgendwann die eigentliche Objektinstanz zugewiesen wird. Eigentlich funktioniert das genau wie mit einer Integer- oder String-Variable. Es gibt noch andere und bessere Lösungen, aber so kann man das schon auch realisieren. |
AW: Verwenden von Pointern
Zitat:
Delphi-Quellcode:
Edit: Der Vollständigkeit halbar das ganze noch mit einem Record:
var
str1, str2: String; int1, int2: Integer; obj1, obj2: TMyClass; begin str1 := 'hallo'; str2 := str1; str1 := 'bye'; // hiernach ist str1 = 'bye' und str2 = 'hallo' int1 := 1; int2 := int1; int1 := 2; // hiernach ist int1 = 2 und int2 = 1 obj1 := TMyClass.Create; obj1.SomeProperty := 1; obj2 := obj1; obj1.SomeProperty := 2; // hier hingegen sind obj1.SomeProperty und obj2.SomeProperty = 2 end;
Delphi-Quellcode:
Mit Strings läuft das übrigens eigentlich genau so ab.
var
rec1, rec2: TMyRec; begin rec1.SomeValue := 1; rec2 := rec1; // bis hier hin sind rec1 und rec2 IDENTISCH, nicht nur gleich. Beide Variablen greifen auf den SELBEN Speicher zu rec2.SomeValue := 2; // Und hier greift dann compiler magic (copy-on-write genannt): Es wurde im Hintergrund eine Kopie angelegt. Nunmehr zeigt nur noch rec1 auf den anfänglichen Speicher, rec2 hat automatisch eine völlig eigene Instanz erhalten. end; |
AW: Verwenden von Pointern
Was ich eigentlich vorhabe ist, dass ich in den Units in denen sich Formulare befinden so weinig wie möglich Code habe.
Mein Hauptprogramm habe ich eigentlich in einer Unit ohne Formular. Dieses habe ich als Klasse geschrieben. Ich will nun onCreate von Form1 eine instanz dieser Klasse erstellen, auf Welche dann alle Forms zugreifen. Dreh- und Angelpunkt ist somit also nicht mehr die unit mit Form1, sondern mein Objekt. Innerhalb dieses Objektes sind dann halt verschiedenste methoden und Variablen (unter anderem auch ein record) auf die aber alle forms irgendwann dann mal zugreifen. Inwiefern das nun sinnvoll ist, kann ich nicht einschätzen, aber auf jeden Fall übt es mich im Umgang mit der Objektorientierung. Wie ich mein Problem nun löse: Ich schreibe einfach in allen Units, wo es erforderlich ist meine Unit, in der ich das Objekt erstellt habe in USES. Dann kann ich das ja direkt über Form1.Core ansprechen, egal in welcher Unit ich dann bin :D Aber danke für die vielen Vorschläge, das hat mich wieder etwas schlauer gemacht. |
AW: Verwenden von Pointern
Dein Ansatz ist sehr sinnvoll, da Du so eine gute Trennung zwischen Businesslogik und GUI erhältst. :thumb:
Schau Dir mal weiter obden den Hinweis zum Singleton an. Damit kannst Du immer genau eine Instanz einer Klasse sicher stellen. Wie Du es genau realiseren kannst hängt auch von Deiner Delphiversion ab und ob Di die Instanz Deiner Klasse schon zur Designtime benötigst, z.B. um irgendwelche Einstellungen im Objketinspektor vorzunehmen. Du könntest z.B. in der Unit Deiner Klasse eine öffentliche Variable MyObjekt definieren und dieser in Deinem Constructor "Self" zuweisen und im Destructor nil. Sofern Du nur eine Instanz Deiner Klasse erzeugst, würde das funktionieren. |
AW: Verwenden von Pointern
Ich würde den Constructor der entsprechenden Forms überschreiben (die Klasse als Parameter mitschicken), also diese Forms nicht von der dpr-Datei verwalten lassen.
Delphi-Quellcode:
type
TFormA = class(TForm) .. private FKlasse: TKlasse; end; .. procedure TFormA.FormCreate(Sender: TObject); begin FKlasse:= TKlasse.Create; FormB:= TFormB.Create(Self, FKlasse); end; procedure TFormA.FormDestroy(Sender: TObject); begin FKlasse.Free; FormB.Free; end;
Delphi-Quellcode:
type
TFormB = class(TForm) .. private FKlasse: TKlasse; public constructor Create(AOwner: TComponent; const Klasse: TKlasse); reintroduce; overload; end; constructor TFormB.Create(AOwner: TComponent; const Klasse: TKlasse); begin inherited Create(AOwner); FKlasse:= Klasse; end; |
AW: Verwenden von Pointern
Hallo,
warum jetzt wieder die Klasse im Form ??? Eine globale Unit mit Singleton ! Heiko |
AW: Verwenden von Pointern
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz