![]() |
OOP: Object als Wrapper
Hey there
Als ich wieder einmal eine Wrapperklasse schreiben wollte, kam mir die Idee, anstatt wie üblich TObject als Basisklasse zu verwenden, object zu nehmen:
Delphi-Quellcode:
Obwohl das ja veraltet ist, sehe ich einige Vorteile: Man kann damit ganz einfach Funktionen kapseln, hat jedoch kein Overhead von TObject (vorallem wenn man eh nur ein einziges Feld wie z.B. ein Handle hat) und die Verwendung ist ein wenig praktischer, da das Instantiieren wegfällt. (Oder? :gruebel: )
type
Wrapper = object end; Ein Beispiel:
Delphi-Quellcode:
Anwendung:interface type WWindow = object(Wrapper) private FHandle: HWND; function GetTopMost: Boolean; procedure SetTopMost(const Value: Boolean); public function Find(const Caption: string): Boolean; property Handle: HWND read FHandle write FHandle; property TopMost: Boolean read GetTopMost write SetTopMost; end; implementation function WWindow.Find(const Caption: string): Boolean; begin FHandle:= FindWindow(nil, PChar(Caption)); Result:= FHandle <> 0; end; function WWindow.GetTopMost: Boolean; begin Result:= (GetWindowLong(FHandle, GWL_EXSTYLE) and WS_EX_TOPMOST) <> 0; end; procedure WWindow.SetTopMost(const Value: Boolean); const InsertAfter: array[Boolean] of HWND = (HWND_NOTOPMOST, HWND_TOPMOST); begin SetWindowPos(FHandle, InsertAfter[Value], 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW); end;
Delphi-Quellcode:
Ich finde, das sieht eigentlich ganz praktisch aus... Nur gibt es bei der Zuweisung von TopMost eine AV, wenn er in SetTopMost auf FHandle zugreifen will. ABER: Wenn ich SetTopMost direkt aufrufe, funktioniert alles tadellos... :cyclops:
var
Window: WWindow; begin assert(Window.Find('Unbenannt - Editor')); Window.TopMost:= True; end Woran kann das liegen? Ich meine, es wird wohl schon ein Grund geben, warum object veraltet ist... Gruss Shaman |
Re: OOP: Object als Wrapper
*schwupps*
|
Re: OOP: Object als Wrapper
wo ist jetzt eigentlich der Unterschied ob du Object oder TObject nimmst (außer das eines wohl veraltet ist)? Hast du eventuell vergessen mit Create die Instanz zu erzeugen.
[Edit]Ich zieh meinen Beitrag zurück. Ich finde zwar nix richtighes zu Object in der Hilfe was das richtige sein könnte aber es scheint kein TObject zu sein sondern nur ein Record mit Funktionen.[/Edit] |
Re: OOP: Object als Wrapper
Hallo Shaman,
ich habe mir den erzeugten Assemblercode einmal angesehen. Obwohl beide Varianten (Zugriff über Property und Aufruf des Setters) eigentlich das gleiche bewirken, wird für den Property-Zugriff ein falscher Code erzeugt, der im schlimmsten Fall Speicherinhalte an ungewollten Stellen überschreibt. Da Borland die Verwendung von Properties im alten Objektmodell nicht offiziell dokumentiert hat, ist von einer Verwendung abzuraten, auch wenn der Compiler die Konstrukte ohne Fehlermeldung übersetzt. Der direkte Aufruf der Setter-Methoden sollte ohne Probleme möglich sein. Gruß Hawkeye |
Re: OOP: Object als Wrapper
@Hawkeye: Danke dir, das ist schon mal aufschlussreich. Kennst Du denn irgend eine Doku für dieses Objektmodell? Es stammt wahrscheinlich noch von Object Pascal, nehme ich an? Es würde mich nämlich schon interessieren...
|
Re: OOP: Object als Wrapper
Das "alte" Objektmodell aus Turbo Pascal kennt keine Konstruktoren/Destruktoren und keine Referenzen d.h.
Man hat die Möglichkeiet ein Objekt statisch anzulegen oder dynamisch mit Hilfe eines Zeigers. In diesem Fall muß man sich dann um die entsprechende Referenzierung/Dereferenzierung mit Hilfe von ^ kümmern. Es gibt keine Zwangserbschema ( allss erbt von TObject) und keine Referenzzählung. |
Re: OOP: Object als Wrapper
D.h. es ist eigentlich ein Recordtyp, welches ebenfalls Methoden beinhalten kann. Deshalb würde es sich IMHO hervorragend für Fälle wie im obigen Beispiel eignen... Aber wieso funktionieren Properties nicht richtig? :?
|
Re: OOP: Object als Wrapper
Hallo Shaman,
das Objektmodell wurde mit "Turbo Pascal 5.5" eingeführt. Borland bietet den Compiler im Museum zum ![]() Gruß Hawkeye |
Re: OOP: Object als Wrapper
Zitat:
|
Re: OOP: Object als Wrapper
Zitat:
Delphi-Quellcode:
type
PBase = ^TBase; TBase = object constructor Init; destructor Done; virtual; end; constructor TBase.Init; begin end; destructor TBase.Done; begin end; var b: TBase; p: PBase; begin b.Init; b.Done; p := New(PBase, Init); Dispose(p, Done); end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:18 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 by Thomas Breitkreuz