Objekte in MSElang

Forum für alles rund um die MSEide und MSEgui
mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Objekte in MSElang

Beitrag von mse »

Ich habe Objekte in MSElang implementiert:
https://gitlab.com/mseide-msegui/mselan ... ng_objects
MSElang Objekte vereinen FPC "record", "object" und "class". Sie können sowohl auf dem Stack als auch im Heap instantiiert werden.

Was meint ihr dazu?

Hier ein weiterer Leistungsvergleich auf Linux X86, Testprogramm im Anhang:

Code: Alles auswählen

 
MSElang with LLVM 3.8.0 -O3
 
time ./test1.bin
 
real    0m2.582s
user    0m2.467s
sys     0m0.111s
Binary size 18088 bytes after strip.
 
FPC 3.0.3 -O3:
 
time ./test1_fpc
 
real    0m4.074s
user    0m3.955s
sys     0m0.119s
Binary size 26072 bytes after strip.
 

Code: Alles auswählen

 
program test1;
 
{$ifdef FPC}{$mode objfpc}{$h+}{$goto on}{$endif}
const
 stringcount = 2000000;
 defaultmwcseedw = 521288629;
 defaultmwcseedz = 362436069;
type
{$ifdef FPC}
 card8 = byte;
 card32 = cardinal;
 char8 = char;
 string8 = string;
{$endif}
 mwcinfoty = record
  fw,fz: card32; //call checkmwcseed() after init
 end;
 pstring8 = ^string8;
 pcard8 = ^card8;
 ppointer = ^pointer;
 pointerarty = array of pointer;
 arraysortcomparety = function (const l,r: ppointer): int32;
// arraysortcomparety = function (const l,r): int32;
 
function comparestring(const l,r: ppointer): int32;
var
 pl,pr,pe: pcard8;
 c: int8;
 i1,i2: int32;
begin
 result:= 0;
 pl:= l^;
 pr:= r^;
 if pl <> pr then begin
  if pl = nil then begin
   result:= -1;
  end
  else begin
   if pr = nil then begin
    result:= 1;
   end
   else begin
    i1:= length(string8(pointer(pl)));
    i2:= length(string8(pointer(pr)));
    if i1 < i2 then begin
     pe:= pl+i1;
     while pl < pe do begin
      c:= pl^-pr^;
      if c <> 0 then begin
       result:= c;
       exit;
      end;
      inc(pl);
      inc(pr);
     end;
    end
    else begin
     pe:= pr+i1;
     while pr < pe do begin
      c:= pl^-pr^;
      if c <> 0 then begin
       result:= c;
       exit;
      end;
      inc(pl);
      inc(pr);
     end;
    end;
    result:= i1-i2;
   end;
  end;
 end;
end;
 
procedure sortarray(var dest: pointerarty; {const} compare: arraysortcomparety);
var
 ar1: pointerarty;
 step: integer;
 l,r,d: ppointer;
 stopl,stopr,stops: ppointer;
 sourcepo,destpo: ppointer;
 acount: integer;
label
 endstep;
begin
 setlength(ar1,length(dest));
 sourcepo:= pointer(dest);
 destpo:= pointer(ar1);
 step:= 1;
 acount:= length(dest);
 while step < acount do begin
  d:= destpo;
  l:= sourcepo;
  r:= sourcepo + step;
  stopl:= r;
  stopr:= r+step;
  stops:= sourcepo + acount;
  if stopr > stops then begin
   stopr:= stops;
  end;
  while true do begin //runs
   while true do begin //steps
    while compare(l,r) <= 0 do begin //merge from left
     d^:= l^;
     inc(l);
     inc(d);
     if l = stopl then begin
      while r <> stopr do begin
       d^:= r^;   //copy rest
       inc(d);
       inc(r);
      end;
      goto endstep;
     end;
    end;
    while compare(l,r) > 0 do begin //merge from right;
     d^:= r^;
     inc(r);
     inc(d);
     if r = stopr then begin
      while l <> stopl do begin
       d^:= l^;   //copy rest
       inc(d);
       inc(l);
      end;
      goto endstep;
     end;
    end;
   end;
endstep:
   if stopr = stops then begin
    break;  //run finished
   end;
   l:= stopr; //next step
   r:= l + step;
   if r >= stops then begin
    r:= stops-1;
   end;
   if r = l then begin
    d^:= l^;
    break;
   end;
   stopl:= r;
   stopr:= r + step;
   if stopr > stops then begin
    stopr:= stops;
   end;
  end;
  d:= sourcepo;     //swap buffer
  sourcepo:= destpo;
  destpo:= d;
  step:= step*2;
 end;
 if sourcepo <> pointer(dest) then begin
  dest:= ar1;
 end;
end;
 
 
function mwcnoise(var state: mwcinfoty): card32;
begin
 with state do begin
  fz:= 36969 * (fz and $ffff) + (fz shr 16);
  fw:= 18000 * (fw and $ffff) + (fw shr 16);
  result:= fz shl 16 + fw;
 end;
end;
 
procedure test1();
var
 mwc: mwcinfoty;
 ar1: array of string8;
 i1,i2: int32;
 ch1: char8;
begin
 mwc.fw:= defaultmwcseedw;
 mwc.fz:= defaultmwcseedz;
 setlength(ar1,stringcount);
 for i1:= 0 to high(ar1) do begin
  mwcnoise(mwc);
  setlength(ar1[i1],card8(mwcnoise(mwc)));
  for i2:= 1 to length(ar1[i1]) do begin
   ch1:= char8(card8(((mwcnoise(mwc) and $ff) * 95) div 255 + 32)); //32..127
   ar1[i1][i2]:= ch1;
  end;
 end;
 sortarray(pointerarty(pointer(ar1)),@comparestring);
 for i1:= 1 to high(ar1) do begin
{
  if ar1[i1] = '' then begin
   writeln(i1,':');
  end
  else begin
   writeln(i1,':',card8(ar1[i1][1]),': ', ar1[i1]);
  end;
}

  if ar1[i1-1] > ar1[i1] then begin
   exitcode:= 1;
   exit;
  end;
 end;
end;
 
 
begin
 test1();
end.
 
Dateianhänge
test1.pas
(3.86 KiB) 95-mal heruntergeladen

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Objekte in MSElang

Beitrag von Christian »

Kann mselang jetzt schon für alle llvm targets code erzeugen ? oder nur für x86
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Objekte in MSElang

Beitrag von kupferstecher »

mse hat geschrieben:MSElang Objekte vereinen FPC "record", "object" und "class". Sie können sowohl auf dem Stack als auch im Heap instantiiert werden.
Was meint ihr dazu?

Hallo MSE,

so wie ich es jetzt verstanden habe, soll Objekt und Record zusammengefasst werden zu "Object" für statischen Speicher und "Class" bleibt "Class" für den Heap. Oder sind noch andere Möglichkeiten angedacht?

Den Begriff 'Object' würde ich auf jeden Fall vermeiden. Einerseits wegen "Klassenobjekten", andererseits scheint doch ein anderes Konzept wie bei FreePascal dahinter zu stehen. Dann lieber noch 'Record'.


Grüße
Kupferstecher

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Objekte in MSElang

Beitrag von mschnell »

mse hat geschrieben:MSElang Objekte vereinen FPC "record", "object" und "class". Sie können sowohl auf dem Stack als auch im Heap instantiiert werden.
Was meint ihr dazu?

Genau das habe ich im fpc-Forum vorgeschlagen, als die Records mit Funktionen eingebaut worden sind. Wolle aber natürlich keiner was von wissen :D

Wie wird gesteuert, ob das Objekt auf Stack oder Heap angelegt wird ?
Kann ein Objekt auch statisch (an einer festen RAM-Adresse) angelegt sein ? (Bei Turbo-Pascal Objekten und Records geht das.)
Werden die Objekte genullt, auch wenn sie nicht explizit (auf dem Heap) angelegt werden ?
Gibt es "destroy" / "free" etc bei allen Objekten - auch auf dem Stack (und statisch) ?
Braucht man bei Objekten auf dem Stack kein "Create" ?
Funktioniert Vererbung (Aufruf des Typs eines Vorfahren) auch bei Stack-Objekten ?

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Objekte in MSElang

Beitrag von mse »

Christian hat geschrieben:Kann mselang jetzt schon für alle llvm targets code erzeugen ? oder nur für x86

Der MSElang/MSEpas Compiler erzeugt LLVM-bitcode:
http://llvm.org/docs/BitCodeFormat.html
welcher vom LLVM-System optimiert und entweder zu Maschinencode übersetzt wird oder in einer Runtime-Umgebung ausgeführt oder Just-In-Time übersetzt wird. Der erzeugte LLVM-bitcode ist Prozessor unabhängig und kann somit für alle LLVM-Targets verwendet werden. MSElang muss lediglich die Target-Pointer-Grösse und Alignments berücksichtigen.

kupferstecher hat geschrieben:so wie ich es jetzt verstanden habe, soll Objekt und Record zusammengefasst werden zu "Object" für statischen Speicher und "Class" bleibt "Class" für den Heap. Oder sind noch andere Möglichkeiten angedacht?

"object" fasst Free Pascal "record", "object" und "class" zusammen. MSElang "class" ist ein "object" das immer auf dem Heap angelegt wird und beim Elementezugriff eine implizite Dereferenzierung vornimmt. Im Prinzip ist "class" redundant, da es in MSElang "^object" entspricht. Ein eigener Bezeichner ist vielleicht trotzdem zur klaren Unterscheidung nützlich, vor allem für Anwender welche Free Pascal gewohnt sind.

Code: Alles auswählen

 
type
 objty = object
  f1: int32;
  constructor create();
  destructor destroy();
 end;
 
 tobj = class(objty)
 end;
 
constructor objty.create();
begin
end;
 
destructor objty.destroy();
begin
end;
 
//[...]
 
var
 obj1: objty;   //an instance on stack
 obj2: ^objty;  //an instance on heap
 objcla1: tobj; //an instance on heap
 
begin
 obj1.f1:= 123;
 
 obj2:= objty.create();
 obj2^.f1:= 123;
 obj2.destroy();
 
 objcla1:= tobj.create();
 objcla1.f1:= 123;
 objcla1.destroy();
 

Den Begriff 'Object' würde ich auf jeden Fall vermeiden. Einerseits wegen "Klassenobjekten", andererseits scheint doch ein anderes Konzept wie bei FreePascal dahinter zu stehen. Dann lieber noch 'Record'.

Free Pascal kennt "object" seit Urzeiten:
https://www.freepascal.org/docs-html/cu ... x59-770005
"object" ist das Grundelement für die objektorientierte Programmierung in MSElang, darum finde ich "object" besser als "record".
mschnell hat geschrieben:Wie wird gesteuert, ob das Objekt auf Stack oder Heap angelegt wird ?

Siehe oben.
Kann ein Objekt auch statisch (an einer festen RAM-Adresse) angelegt sein ? (Bei Turbo-Pascal Objekten und Records geht das.)

Ja, via Link-Attributen. Syntax ist noch nicht definiert.
Werden die Objekte genullt, auch wenn sie nicht explizit (auf dem Heap) angelegt werden ?

Normalerweise ja, kann aber mit "nozeroinit" abgeschaltet und mit "zeroinit" in Nachkommen wieder eingeschaltet werden.

Code: Alles auswählen

 
type
 objty = object [nozeroinit] //instances are not inited
  f1: int32;
  constructor create();
  destructor destroy();
 end;
 
 tobj = class(objty) [zeroinit] //instances are inited
 end;
 

Gibt es "destroy" / "free" etc bei allen Objekten - auch auf dem Stack (und statisch) ?

Man kann "constructor"en und "destructor"en bei allen Instantiierungsarten aufrufen. Die Erzeugung eines Heap-Objektes ist nur mit einem "constructor" möglich.

Code: Alles auswählen

 
type
 objty = object
  f1: int32;
  constructor create();
  destructor destroy();
 end;
 
 objaty = object //an object without constructor and
                 //destructor, can not be on heap
  f1: int32;
 end;
 
constructor objty.create();
begin
 f1:= 123;
end;
 
destructor objty.destroy();
begin
end;
 
//[...]
 
var
 obj1: objty;   //an instance on stack
 obj2: ^objty;  //an instance on heap
begin
 obj1.create(); //sets obj1.f1
 obj1.destroy(); //does nothing
 
 obj2:= objty.create(); //gets memory and sets obj2^.f1
 obj2.destroy();        //frees memory
 

Braucht man bei Objekten auf dem Stack kein "Create" ?

Nein.
Funktioniert Vererbung (Aufruf des Typs eines Vorfahren) auch bei Stack-Objekten ?

Ja. Objekte mit virtuellen Methoden und Interfaces benötigen das Objektattribut "virtual".

Code: Alles auswählen

 
type
{
 objty = object
  f1: int32;
  method test() [virtual]; //wrong!
 end;
}

 objty = object [virtual]
  f1: int32;
  method test() [virtual];
 end;
 

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Objekte in MSElang

Beitrag von kupferstecher »

mse hat geschrieben:Im Prinzip ist "class" redundant, da es in MSElang "^object" entspricht. Ein eigener Bezeichner ist vielleicht trotzdem zur klaren Unterscheidung nützlich, vor allem für Anwender welche Free Pascal gewohnt sind.

Ein eigener Bezeichner ist auf jeden Fall wichtig.

Free Pascal kennt "object" seit Urzeiten:
https://www.freepascal.org/docs-html/cu ... x59-770005
"object" ist das Grundelement für die objektorientierte Programmierung in MSElang, darum finde ich "object" besser als "record".

OK, mir war nicht klar, dass dein Object auch den vollen OOP-Umfang hat. In diesem Fall passt es ja auch zum FreePascal-Object sehr gut.

Insgesamt sieht mir das Konzept ganz gut aus. Ich würde es immernoch so verstehen, dass bei dir der Typ Record in den Typ Object verschmolzen wird. Die Trennung zwischen Record und Object hat in Freepascal/Delphi vermutlich auch historische Gründe. Der Geschwindigkeitsvorteil von Records mit statischen Elementadressen ist ja auch in Objekten per "mitdenkendem" Compiler möglich.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Objekte in MSElang

Beitrag von Christian »

inwieweit ist mselang denn noch zu objectpascal "abwärts"kompatibel ?
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Objekte in MSElang

Beitrag von mse »

Christian hat geschrieben:inwieweit ist mselang denn noch zu objectpascal "abwärts"kompatibel ?

Im Moment arbeite ich an einem Compiler der den in MSEgui verwendeten Code übersetzen kann, ein Subset von FPC 2.6. Dabei verwende ich die Grundelemente von MSElang. Zum Beispiel wird TObject aus einem MSElang "object" abgeleitet, etwa

Code: Alles auswählen

 
 type
 
 classobjectty = object [virtual,zeroinit]
  constructor create();
  destructor destroy() [virtual];
  procedure free();
  procedure afterconstruction() [virtual,afterconstruct];
  procedure beforedestruction() [virtual,beforedestruct];
  procedure freeinstance() [virtual,fini];
//[...]
 end;
 
 TObject = class(classobjectty)
 end;
 

Der Parser akzeptiert Free Pascal Syntax. Der eigentliche MSElang Dialekt kommt später. Da der Parser von einer Art Grammatik gesteuert wird, dürfte sich der Aufwand in Grenzen halten, wenn Ich bereits jetzt an die Bedürfnisse von MSElang denke.
https://gitlab.com/mseide-msegui/mselan ... rammar.gra
Das wird von
https://gitlab.com/mseide-msegui/mselan ... module.pas
in das Grammatikmodul umgewandelt
https://gitlab.com/mseide-msegui/mselan ... rammar.pas
Das Format hat viel Optimierungspotential. Leider ist LLVM - vermutlich wegen exzessiver Benutzung von "high quality C++ code" - extrem langsam, so dass sich die Optimierung des Parsers vielleicht erübrigt...

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Objekte in MSElang

Beitrag von mschnell »

mse hat geschrieben:Man kann "constructor"en und "destructor"en bei allen Instantiierungsarten aufrufen. Die Erzeugung eines Heap-Objektes ist nur mit einem "constructor" möglich.

Vermutlich hat ein Objekt also einen impliziten Vorfahren (wie in fpc), der ein Create zur Verfügung stellt, das bei Stack (und statischen) Objekten - je nach Attribut - eine Nullung macht und bei Heap-Objekten den Speicher allokiert.

Code: Alles auswählen

 
classobjectty = object [virtual,zeroinit]
 


Die Notation mit eckiger Klammer für Attribute ist gewöhnungsbedürftig , macht aber durchaus Sinn.

Ich vermute, runde Klammern bezeichnen den Vorfahren ?!?

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Objekte in MSElang

Beitrag von mse »

mschnell hat geschrieben:
mse hat geschrieben:Man kann "constructor"en und "destructor"en bei allen Instantiierungsarten aufrufen. Die Erzeugung eines Heap-Objektes ist nur mit einem "constructor" möglich.

Vermutlich hat ein Objekt also einen impliziten Vorfahren (wie in fpc), der ein Create zur Verfügung stellt, das bei Stack (und statischen) Objekten - je nach Attribut - eine Nullung macht und bei Heap-Objekten den Speicher allokiert.

Nein,

Code: Alles auswählen

 
type
 objty = object
  [...]
 end;
 

hat keinen Vorfahren. Die Nullung ist ein Spezialfall der Initialisierung von Objekten mit referenzgezählten Feldern welche vom Compiler durchgeführt wird. Wenn man Objekte auf dem Heap anlegen will muss man mindestens einen Konstruktor und einen Destruktor implementieren.

Code: Alles auswählen

 
type
 objty = object
  constructor create();
  destructor destroy();
 end;
 


Code: Alles auswählen

 
classobjectty = object [virtual,zeroinit]
 


Die Notation mit eckiger Klammer für Attribute ist gewöhnungsbedürftig , macht aber durchaus Sinn.

Ich vermute, runde Klammern bezeichnen den Vorfahren ?!?

Ja, danach werden die Interfaces aufgeführt.

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Objekte in MSElang

Beitrag von mschnell »

mse hat geschrieben:
mschnell hat geschrieben:Wenn man Objekte auf dem Heap anlegen will muss man mindestens einen Konstruktor und einen Destruktor implementieren.


Hmmm. Das eigentliche Anlegen der Datenstruktur auf dem Heap wird aber sicher vom Compiler implizit gemacht (was dann genau so aussieht, als gäbe es einen impliziten Vorgänger, der das tut). Aber warum muss man dann (anders als in fpc und Delphi) noch explizit einen (leeren) Constructor und Desctructor hinschreiben ? (Oder entscheidet genau das, dass das Objekt auf dem Heap instanziiert werden soll ?)

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Objekte in MSElang

Beitrag von mse »

mschnell hat geschrieben: (Oder entscheidet genau das, dass das Objekt auf dem Heap instanziiert werden soll ?)

Ja, siehe den Link ins MSElang Wiki.

Code: Alles auswählen

 
type
 objty = object
  f1: int32;
  constructor create();
  destructor destroy();
 end;
 
constructor objty.create();
begin
end;
 
destructor objty.destroy();
begin
end;
 
var
 obj1: objty; //auf dem stack, braucht kein create
 obj2: ^objty;
begin
 obj1.f1:= 123;
 obj2:= objty.create(); //im heap
 obj2^.f1:= 456;
 obj2.destroy();
 

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Objekte in MSElang

Beitrag von mschnell »

mse hat geschrieben:var
obj1: objty; //auf dem stack, braucht kein create
obj2: ^objty;
obj3: ^objty;


Die bisher übliche Schreibweise würde also Stack-Objekre erzeugen und nicht (wie bei Delphi oder fpc "class"-Typen ... "Object"-Typen verwendet ja keiner mehr) Heap Objekte.

Der code
obj1 := objty.create();
würde also vom Compiler nicht akzeptiert, weil obj1 kein Zeiger ist.

obj1.create;
ist natürlich genau so unsinnig wie obj2.create; , müsste aber nicht unbedingt direkt zum Absturz führen.

Interessant wäre aber
obj3 := obj1,create(i: Integer);
z.B. wenn der creator von objty nicht einfach den Vorgänger aufruft, sondern irgendwas mit i tut.

Der code:
obj3 := obj1;
obj3.doit();

obj3 := obj2;
obj3.doit();

würde also erst in der letzten Zeile crashen ?

-Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Objekte in MSElang

Beitrag von mse »

mschnell hat geschrieben:Der code
obj1 := objty.create();
würde also vom Compiler nicht akzeptiert, weil obj1 kein Zeiger ist.

Korrekt.
obj1.create;
ist natürlich genau so unsinnig wie obj2.create; , müsste aber nicht unbedingt direkt zum Absturz führen.

Das ist nicht unsinnig, dann wird create() als normale Methode ausgeführt. Das ist in Delphi auch so.
Interessant wäre aber
obj3 := obj1,create(i: Integer);
z.B. wenn der creator von objty nicht einfach den Vorgänger aufruft, sondern irgendwas mit i tut.

Das wäre dann so:

Code: Alles auswählen

 
    type
     objty = object
      f1: int32;
      constructor create(i: int32);
      destructor destroy();
     end;
 
    constructor objty.create(i: int32);
    begin
     f1:= i;
    end;
 
    destructor objty.destroy();
    begin
    end;
 
    var
     obj3: ^objty;
    begin
     obj3:= objty.create(123); //im heap
     obj3.destroy();
 

Der code:
obj3 := obj1;

Das kompiliert nicht, da die Typen nicht passen.
So gehts:

Code: Alles auswählen

 
program test;
type
 objty = object
  f1: int32;
  constructor create(i: int32);
  destructor destroy();
  method doit();
 end;
 
constructor objty.create(i: int32);
begin
 f1:= i;
end;
 
destructor objty.destroy();
begin
end;
 
method objty.doit();
begin
 writeln(f1);
end;
 
var
 obj1: objty;
 obj2,obj3: ^objty;
begin
 obj1.f1:= 123;
 obj3:= @obj1;
 obj3^.doit();
end.
 

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Objekte in MSElang

Beitrag von mschnell »

mse hat geschrieben:Das kompiliert nicht, da die Typen nicht passen.

Bei Delphi Class Typen (auch bei anderen ? ) wird bei Bedarf automatisch der Pointer verwendet, ohne dass man das explizit angibt. Nicht sauber, aber praktisch. (obj3.doit bedeutet da ja eigentlich obj3^.doit)

Ist die Regel das bei mse-Pascal strenger und/oder klarer definiert ?

-Michael

Antworten