![]() |
Überschreiben von Feldern in OOP
Hallo Leute,
habe momentan ein Problem mit der Vererbung. Das Ziel ist es, z.b. Produkte, Warengruppen, Kunden, etc... als Objekte darzustellen, welche in einer Datenbank gepsichert sind. Habe hierfür ein Minimalbeispiel erstellt. Statt viel rumzuschreiben, hier Bild: ![]() So. Ich will die Methode getPointerByUid in TItemListe implementieren, damit ich den selben Quatsch nicht 1000 mal tippen muss. Diese Mthode sähe in TItemliste so aus:
Delphi-Quellcode:
Dabei sieht die TProdListe.Add methode so aus:
function TItemListe.getPointerByUid(uid:Integer):Pointer;
var i:INteger; begin for i:=1 to self.Count do begin if self.Liste[i-1].uid=uid then begin Result:=@self.Liste[i-1]; exit; end; end; raise ERangeError.Create('Kein ItemListeneintrag gefunden! '+#13+'UID: '+IntToStr(uid)); end;
Delphi-Quellcode:
Nun das Problem:
procedure TProdListe.add(bez:String; preis:Double; (...));
var i:Integer begin i:=length(self.Liste); setLength(self.Liste, i+1); self.Liste[i]:=TProdukt.Create(bez, preis, (...)); end; Wenn die Procedure getPointerByUid in TItemListe läuft, greift diese auf die Liste, deklariert in TItemliste zu. Das ist bad! Diese ist natürlich leer. Sicherlich hat sich der eine oder andere mit diesem Modellproblemen schon beschäftigt. Wie macht ihr das? Wäre für Vorschläge aller Art sehr dankbar! Gruß! |
Re: Überschreiben von Feldern in OOP
1. würde ich mir überlegen, anstatt TList vielleicht TObjectList zu verwenden, dann hört die Pointerschieberei auf und die Typen sind etwas sicherer.
2. würde ich TItemList nicht mit TProduktList erweitern, sondern TProduktList von TTitemList ableiten. So sparst Du Dir die Eigenschaft Liste und kannst direkt darauf zugreifen. 3. TProdukt von TItem ableiten, so hat TProduct eine uid und kann bei der Suche nach selbigem benutzt werden.
Delphi-Quellcode:
function TItemListe.getPointerByUid(uid:Integer):TItem;
var i:INteger; begin Result := nil; for i:=0 to Count-1 do if Items[i].uid=uid then begin Result:=Items[i]; break; end; if Result = nil then raise ERangeError.Create('Kein ItemListeneintrag gefunden! '+#13+'UID: '+IntToStr(uid)); end; rocedure TProdListe.add(bez:String; preis:Double; (...)); var i:Integer begin Add(TProdukt.Create(bez, preis, (...))); end; |
Re: Überschreiben von Feldern in OOP
hi sh17,
habe nicht sofort antworten können. musste ein wenig rumexperimentieren. habe ersteinmal deinen ersten tipp ausprobiert. stoße dabei aber auf schwierigkeiten. :( habe nun die Funktion
Delphi-Quellcode:
umgeschrieben und
getPointerByUid(uid:Integer)
der Rückgabewert ist nun
Delphi-Quellcode:
wobei Liste:TobjectList
Result:=self.Liste.List[i-1];
es wird auch ein Pointer zurückgegeben. ich kann ihn aber nicht typisieren. beim Aufruf
Delphi-Quellcode:
kommt ein access violation... :(
(...)
_prod:^TProdukt; begin _prod:=produkte.getPointerByUid(1); showmessage(_prod.name); end; ich brauche aber unbedingt den pointer zu diesem objekt. sonst laufen die berechnungen alle durcheinander... würde mich freuen, wenn du mir auch hier ein paar tipps geben könntest. werde bald sobald ich ein bisschen zeit habe auch mal die anderen möglichkeiten genauer anschauen. danke schon jetzt! Gruß EDIT: hmmm.. habs glaub ich mit
Delphi-Quellcode:
hinbekommen... muss ich aber etwas genauer testen ob ich mit dem pointer doch nicht auf kopierte instanzen zugreife....
function TItemListe.getPointerByUid(uid:Integer):Pointer;
var i:INteger; erg:TItem; begin for i:=1 to self.Liste.Count do begin if (self.Liste.Items[i-1] as TItem).uid=uid then begin erg:=(self.Liste.Items[i-1] as TItem); Result:=@erg; // Items[i-1] as TItem); exit; end; end; //Result:=nil; raise ERangeError.Create('Kein ItemListeneintrag gefunden! '+#13+'UID: '+IntToStr(uid)); end; |
Re: Überschreiben von Feldern in OOP
Hallo,
Zitat:
Gruß xaromz |
Re: Überschreiben von Feldern in OOP
Zitat:
hat eigentlich alles funktioniert... nur irgendwie bin ich dennoch noch ein wenig unsicher.... bei meinen verketteten Listen hatte ich probleme mit rückgabe in form von ganzen Objekten... die welt ist manchmal echt ein rätsel :-D also in c++ wird definitiv eine kopie von (primitiven zumindest) werten zurückgegeben.. in java referenz.... ich blick da langsam nicht mehr so ganz druch... :( hätte vielleicht jemand für mich einen link, wo ich die "grundlagen" von pascal nachlesen könnte? danke |
Re: Überschreiben von Feldern in OOP
Objkete in Delphi sind Referenzen (also Zeiger). bei primitiven typen kommt es an, wie die Prozeduren/Funktionen deklariert sind.
|
Re: Überschreiben von Feldern in OOP
Zitat:
@mojo: Wertetypen sind grundsätzlich und sprachenunabhängig alle Typen, die auf dem Stack liegen (bei Referenztypen landet stattdessen nur die Adresse als Int auf dem Stack, die Daten liegen auf dem Heap). Bei Pascal wären das primitive Typen, Records, statische Arrays und Rücksprungadressen ^^; in einem speziellen, nicht gerade oft wichtigen Sinne auch Methodenzeiger . Strings sind zwar Referenzen, verhalten sich aber wie Wertetypen. |
Re: Überschreiben von Feldern in OOP
Zitat:
danke! ich habs nun hinbekommen ohne viel code umschreiben zu müssen und dennoch eine elegante lösung zu benutzen! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:07 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