Einzelnen Beitrag anzeigen

Benutzerbild von Dano
Dano

Registriert seit: 12. Aug 2004
49 Beiträge
 
#78

Re: Unbegrenzt viele Nachkommastellen

  Alt 21. Okt 2004, 04:49
Hi Hagen

die beiden links sind gold wert
nach ein paar gemütlichen stunden mit dem debugger (*ironie*^^) habe ich erstmal die ganze genialität der sache regestriert^^
alles habe ich noch nicht raus....aber kommt noch

ich versuch es mal zusammenzufassen:
(ich hoffe du korrigierst mich falls ich irgendwas falsch interpretiere^^)

im grunde nutzen wir nur ein verhalten vom compiler das er bei Interfaces zeigt....
Interfaces wie sie hier benutzt werden sind im prinziep nur zeiger auf eine VMT wobei uns der compiler ein haufen arbeit abnimmt....
im grunde kann man sie wie objekte/klassen verwenden....



1. locale interface variable
var MyIInteger: IInteger hier wird MyIInteger auf dem stack angelegt und mit nil initialisiert
das besondere hierbei ist das sie mit nil intialiesiert wird was bei anderen localen var (z.B. Pointer, Integer) nicht der fall wäre, die haben irgendwelche werte die vorher auf dem stack lagen....
(das so erzeugte MyIInteger würde ich mir in gewisser weise als Pointer vorstellen)


2. funktions/procedur - aufrufe die so ein Interface als parameter haben
NSet(MyIInteger,1); die funktionen testet ob MyIInteger nil ist
if @MyIInteger <> nil then...... wenn sie nil ist dann wird eine funktion aufgerufen die dem interface eine VMT zuweist und speicher reserviert.... dazu komme ich gleich noch
wenn sie nicht nil ist hat sie eine VMT und ist damit bereits initialisiert und kann verwendet werden....


3. zuweisungen
MyIInteger1:= MyIInteger2 hier ruft der compiler automatisch IntfCopy auf
procedure _IntfCopy(var Dest: IInterface; const Source: IInterface); dadurch wird bei Dest der refcounter um 1 erhöht und MyIInteger1 auf die VMT von MyIInteger2 geändert
und bei MyIInteger1 wird der refcounter um 1 verringert... fals er 0 wird, wird die VMT und der speicher von MyIInteger1 frei gegeben
beide interface zeigen jetzt auf die selbe VMT.....
dabei wird kein neuer speicher reserviert... halt wie bei Pointern


4. wenn der gültigkeitsbereich endet
also wenn das ende der funktion erreicht ist wird vom compiler automatisch IntfClear aufgerufen
function _IntfClear(var Dest: IInterface): Pointer; dabei wird der refcounter von MyIInteger um eins verringert
wird er 0, wird die VMT und der speicher von MyIInteger frei gegeben
auch bei MyIInteger:= nil; wird der refcount um 1 für die variable verringert



5. die VMT (Virtual Methode Tabel)
jedes interface hat eine VMT
Delphi-Quellcode:
type
  IInterface = interface
    ['{00000000-0000-0000-C000-000000000046}']
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;
diese 3 methoden müßen von klassen die ein interface nutzen implementiert werden, das macht man am einfachsten in dem man TInterfacedObject als vorfahre der klasse mit einbindet

da unser interface MyIInteger in keine klasse eingebunden ist funktioniert das so nicht
deshalb müßen wir unsere VMT mit den 3 funktionen selber machen

jede funktion die als übergabeparameter eines unserer interfaces hat, prüft ob das interface auf nil zeigt
ist das der fall reservieren wir speicher für ein pointerarray das min. 3 einträge hat
die 3 pointer müßen wir natürlich auf funktionen zeigen lassen die wir selber noch implementieren müssen... die im prinzip das machen was die standartfunktionen eines interfaces machen
außerdem können wir hier auch noch unsere eigenen methoden mit einbauen... indem wir die VMT mit mehr einträgen machen (>3)
auch felder sind möglich, was bei normalen interfaces nicht möglich wäre



Fazit: der compiler übernimmt bei interfaces das was man bei normalen objecten mit create oder free selber machen müßte... man muß sich nicht um das aufräumen kümmern... speicherlecks sind eigentlich ausgeschlossen
allerdings muß man sich um die VMT selber kümmern... das ist zwar im ersten augenblick komplizierter, aber wenn es einmal gemacht ist kann man nie wieder das freigeben oder erstellen von objekten vergessen

in c++ ruft der compiler automatisch den construktor für ein objekt auf wenn es als lokale variable verwendet wird...ebenso den destruktor (natürlich kann man hier auch noch den zeiger auf ein objekt verlieren und ein speicherleck bekommen...)
schade das sowas nicht bei delphie automatisch geht... darum der umweg über die interfaces
aber großes plus bei interfaces ist das refcounting
und kein TObject *juhu*

den overhaed den TObjekt verursacht... *omg*
da haben meine klassen wehniger eigene funktionen und felder als das was sie von TObject aufgedrückt bekommen....
eigentlich auch schade das man klassen nicht ohne TObjekt erstellen kann
andererseits hat die VCL auch vorteile was besonders das RAD betrifft... interaktionen mit dem benutzer der anwendung werden doch extrem vereinfacht...


naja, ist bissel verworen was ich da geschrieben habe... aber ich denke mal das es halbwegs richtig ist^^
ich schnapp mir morgen erstmal das asm-buch.... hab mit tasm noch nix gemacht... nur masm... und da wird einiges anders sein bei pascal

lustig fand ich nur das ich die asm-funktion von waitcursor schneller kapiert habe als das delphie-construckt^^
kleiner schneller sauberer
naja... ich lerne ja erst noch den delphi-syntax

mfg Dano
  Mit Zitat antworten Zitat