Record, Object, Class. Warum nicht nur Object?

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Record, Object, Class. Warum nicht nur Object?

Beitrag von Soner »

Ich habe heute Record, Object und Class-Typen näher angeschaut und eigentlich kann man mit Object die anderen beiden ersetzen.
Object-Typen können ohne Prozeduren und Funktionen wie Records benutzt werden dann sind die gleich schnell wie Records (beim erstellen, benutzen und freigeben).
Kleinere Objekte muss man nicht mal erstellen, man kann es einfach als VAriable definieren und benutzen.
Man kann ein Object auch wie Klassen benutzen, dann sind sie genauso schnell/nutzbar wie Klassen (class-Objekte).

Ist es nicht besser wegen einfachheit Records und Klassen zu verzichten und nur noch Object-Typen zu benutzen?

Hier habe ich ein Test für erstellen, "benutzen" und freigeben:

Code: Alles auswählen

 
Type            erstellt        benutzt         freigegeben in ms
...
======================
Testreihe 7
TObj            2.312846        0.091706        0.972155
TObjRec         0.906797        0.157406        0.812354
TRec            0.916379        0.092048        0.822277
TClass          2.286156        0.093417        1.145644
======================
Testreihe 8
TObj            2.336800        0.091706        0.972155
TObjRec         0.882502        0.091706        0.788743
TRec            0.912615        0.092391        0.796955
TClass          2.303950        0.100945        1.167202
======================
Testreihe 9
TObj            2.315584        0.091364        0.972155
TObjRec         0.907824        0.091706        0.794218
TRec            0.890372        0.091706        0.796955
TClass          2.303265        0.093075        1.145302
======================
Testreihe 10
TObj            2.311136        0.091364        1.004321
TObjRec         0.963943        0.091364        0.788743
TRec            0.914668        0.092048        0.796955
TClass          2.274864        0.093075        1.146329
 


Das ist das Programm das ich verwendet habe zum Testen:

Code: Alles auswählen

 
program ObjClassRecordDemo;
uses windows;
type
 
  { TObj }
  TObj = object
    X: integer;
    constructor Init;
    destructor Done;
  end;
  PObj = ^TObj;
 
  TObjRec = object
    X: integer;
  end;
  PObjRec = ^TObjRec;
 
  TRec= record
    x: integer;
  end;
  PRec=^TRec;
 
  TClass = class
    X: integer;
    constructor Create;
  end;
 
{ TObj }
constructor TObj.Init;
begin
  X:=1;
end;
 
destructor TObj.Done;
begin
end;
 
{TClass}
constructor TClass.Create;
begin
  X:=1;
end;
 
const ObjCount = 30000;
var //myObj: PObj;
    ObjList: array[0..ObjCount-1] of PObj;
    ORList: array[0..ObjCount-1] of PObjRec; //wie record erstellen
    RecList: array[0..ObjCount-1] of PRec;
    ClassList: array[0..ObjCount-1] of TClass;
    erstellt, benutzt, freigeg: single;
 
    i, reihe: integer;
var
  aFreq: Int64;
  aStart: Int64;
  aEnd: Int64;
begin
  QueryPerformanceFrequency(aFreq);
  Writeln('Type',#9#9,'erstellt',#9,'benutzt',#9#9,'freigegeben in ms');
  for reihe:=1 to 10 do begin
    WriteLn('Testreihe ',reihe,#13);
    // TObj
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      New(ObjList[i],Init);
    end;
    QueryPerformanceCounter(aEnd);
    erstellt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      if ObjList[i]^.X=1 then ObjList[i]^.X:=10;
    end;
    QueryPerformanceCounter(aEnd);
    benutzt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      Dispose(ObjList[i],Done);
    end;
    QueryPerformanceCounter(aEnd);
    freigeg:=((aEnd - aStart) * 1000 / aFreq);
    Writeln('TObj ',#9#9,erstellt:3:6,#9,benutzt:3:6,#9,freigeg:3:6);
 
    // TObjrecord
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      New(ORList[i]);
      ORList[i]^.X:=1;
    end;
    QueryPerformanceCounter(aEnd);
    erstellt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      if ORList[i]^.X=1 then ORList[i]^.X:=10;
    end;
    QueryPerformanceCounter(aEnd);
    benutzt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      Dispose(ORList[i]);
    end;
    QueryPerformanceCounter(aEnd);
    freigeg:=((aEnd - aStart) * 1000 / aFreq);
    Writeln('TObjRec ',#9,erstellt:3:6,#9,benutzt:3:6,#9,freigeg:3:6);
 
    // REcord ==================
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      New(RecList[i]);
      RecList[i]^.x:=1;
    end;
    QueryPerformanceCounter(aEnd);
    erstellt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      if RecList[i]^.X=1 then RecList[i]^.X:=10;
    end;
    QueryPerformanceCounter(aEnd);
    benutzt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      Dispose(RecList[i]);
    end;
    QueryPerformanceCounter(aEnd);
    freigeg:=((aEnd - aStart) * 1000 / aFreq);
    Writeln('TRec ',#9#9,erstellt:3:6,#9,benutzt:3:6,#9,freigeg:3:6);
 
 
    // Class ==================
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      ClassList[i]:=TClass.Create;
    end;
    QueryPerformanceCounter(aEnd);
    erstellt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      if ClassList[i].X=1 then ClassList[i].X:=10;
    end;
    QueryPerformanceCounter(aEnd);
    benutzt:=((aEnd - aStart) * 1000 / aFreq);
 
    QueryPerformanceCounter(aStart);
    for i:=0 to ObjCount-1 do begin
      ClassList[i].Free;
    end;
    QueryPerformanceCounter(aEnd);
    freigeg:=((aEnd - aStart) * 1000 / aFreq);
    Writeln('TClass ',#9#9,erstellt:3:6,#9,benutzt:3:6,#9,freigeg:3:6);
 
    WriteLn('====================== ');
  end; //von reihe
 
  WriteLn('[Enter] druecken zum Beenden.'); readln;
end.
 

Euklid
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 10:38
OS, Lazarus, FPC: Lazarus v2.0.10, FPC 3.2.0
Wohnort: Hessen
Kontaktdaten:

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Euklid »

Also ich gehe sehr gerne mit Records um, weil die sehr schlank und ungeheuer einfach in der Handhabung sind.

Viele Grüße, Euklid

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: Record, Object, Class. Warum nicht nur Object?

Beitrag von mse »

Soner hat geschrieben:Ich habe heute Record, Object und Class-Typen näher angeschaut und eigentlich kann man mit Object die anderen beiden ersetzen.

Einverstanden, siehe auch wie Objekte in MSElang implementiert wurden:
viewtopic.php?f=53&t=10729

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: Record, Object, Class. Warum nicht nur Object?

Beitrag von mschnell »

Die mse-Implementierung kommt mir sehr gut vor ! Explizite Typ-Namenen für Record, Object und Class sind definitiv nicht nötig, wenn der gemeinsame Type flexibel genug ist (siehe der von mse angegeben Link).

Die Namens-Gebung finde ich aber kritisch. Für mein Begriffe hat sich - unabhängig von der jeweiligen Sprache und anders als in Turbo-Pascal - "Klasse" als Typ und "Objekt" als Instanz eins solchen Typs eingebürgert.

-Michael

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Soner »

@Euklid:
Das gute an Objekten ist ja, dass sie genauso einfach verwendet werden kann. Der Vorteil ist, wenn das Objekt umfangreich wird, dann kann man es mit Methoden erweitern. Man mußte nicht, dafür noch Records mit Methoden erfinden.:

Code: Alles auswählen

 
type
  TObj = object
    x,y : integer;
  end;
  PObj = ^TObj;
 
  TRec = record
    x,y: integer;
  end;
  PRec = ^TRec;
 
 
var
  //statisch
 statobj: TObj;
 statrec: TRec;
 //dynamisch
 dynObj: PObj;
 dynRec: PObj;
 
begin
   //statisch
   statobj.x:=10;
   dynObj.y:=statobj.x;
  //...
 
  //dynamisch
  New(dynObj);
  New(dynRec);
 
  dynObj^.x:=10;
  dynRec^.x:=dynObj^.x;
 
 Dispose(dynObj);
 Dispose(dynRec);
end;
 


@mse
???
Hier steht dass du Klassen verwendest. https://gitlab.com/mseide-msegui/mselang/wikis/home/mselang_objects#classes
Ich meine Komplett streichen, das Wort "class" und "record" komplett streichen und nur "Object" benutzen. Das wurde Sprachwirrwarr minimieren und wahrschlich würde dann der Compiler leichter zu warten und auf Leistung zu trimmmen sein.

@mschnell
Mse verwendet auch Klassen:
https://gitlab.com/mseide-msegui/mselang/wikis/home/mselang_objects#classes

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Warf »

Da ich viele C++ Anfänger kenne, die genau damit Probleme haben (wann ist es ein Zeiger, wann ein Speicherblock). Die frage wann der Dereferenzierungsoperator verwendet werden muss und wann nicht kommt mir mittlerweile zu den Ohren raus.

Also ich bin dagegen, da ich denke dass es bei weniger erfahrenen Entwicklern wahrscheinlich zu viel mehr Problemen führen wird. MMn ist jede Verwendung des Dereferenzierungsoperators für neu Einsteiger ein Grund mehr, die Sprache nicht zu lernen. Swift, C#, Python, etc. alle Sprachen welche aktuell sehr beliebt sind, aufgrund ihrer Einfachheit, gehen genau diesen Weg, weg vom dereferenzierungsoperator, sondern zur strikten (namentlichen und logischen) trennung zwischen Referenzen und Speicherblöcken. Und es funktioniert sehr gut.

Daher denke ich das es gut ist so wie es Aktuell gelöst ist, mit Klassen als Instanzkonzept, Records als Stackvariablen und Objects als allarounder. Somit ist für jeden was dabei. Man muss die Sprache ja nicht komplizierter machen, indem man Features entfernt.

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Soner »

@warf:
Man kann ja Dereferenzierungsoperators auch entfernen, wie man es bei Klassen getan hat.
Wenn man Speicheradresse ansprechen will, dann kann man es immer noch mit @ tun.

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: Record, Object, Class. Warum nicht nur Object?

Beitrag von mse »

Soner hat geschrieben:@mse
???
Hier steht dass du Klassen verwendest. https://gitlab.com/mseide-msegui/mselang/wikis/home/mselang_objects#classes
Ich meine Komplett streichen, das Wort "class" und "record" komplett streichen und nur "Object" benutzen. Das wurde Sprachwirrwarr minimieren und wahrschlich würde dann der Compiler leichter zu warten und auf Leistung zu trimmmen sein.

In MSElang ist "class" tatsächlich redundant, es entspricht "^object". Zudem ist gewährleistet, dass "class" nicht auf dem Stack alloziert werden und die Weitergabe immer als Pointer mit ihrer fixen Grösse geschieht. Weiter bieten "class" die implizite Dereferenzierung. Im Moment scheint mir der Nutzen von "class" grösser als der Nachteil eines weiteren Typs. Es gab auch Opposition gegen das Weglassen von "class".
Ein "class" Typ kann von einem "object" Typen abgeleitet werden:

Code: Alles auswählen

 
type
 objty = object
  f1: int32;
  f2: int32;
  constructor create();
  destructor destroy();
 end;
 
 ctest = class(objty)
 end;
 
constructor objty.create();
begin
end;
 
destructor objty.destroy();
begin
end;
 
var
 ct1: ctest;
 obj1: objty;
 obj2: ^objty;
 
begin
 ct1:= ctest.create();
 ct1.f1:= 123;
 ct1.destroy();
 
 obj1.f1:= 123;
 
 obj2:= objty.create();
 obj2^.f1:= 123;
 obj2.destroy();
 

Intern benutzen "class" und "object" die selben Compiler-Mechanismen.
Zuletzt geändert von mse am So 4. Jun 2017, 20:12, insgesamt 1-mal geändert.

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Soner »

Vielleicht sollte man Zeigeroperator "^" aus Anweisungsblock komplett entfernen und nur bei Type- und Variablendefinition benutzen. Und wenn man dann in Anweisungsblock Zeigertypen verwendet, dann meint man immer den Wert nicht die Adresse:

Code: Alles auswählen

 
var i: ^integer;
begin
   i:= 1; //Neuer Standard: Wert ansprechen nicht die Speicheradresse
  @i:=1; //Speicheradresse ansprechen
end;
 

Dann hätte man auch einheitliche Zeigerbehandlung für alle Arten von Typen.

Man könnte auch bei Objecterstellung auf Heap, Kontruktionen wie:
MyClass:=TMyClass.Create(xyz);
verzichten, und New verwenden, wie bei Variablen:
New(MyClass, Create(xyz));

Das wäre große Vereinfachung für die Sprache, man könnte Hunderte von Seiten aus Programmierhandbüchern streichen. :D

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: Record, Object, Class. Warum nicht nur Object?

Beitrag von mse »

Soner hat geschrieben:Vielleicht sollte man Zeigeroperator "^" aus Anweisungsblock komplett entfernen und nur bei Type- und Variablendefinition benutzen. Und wenn man dann in Anweisungsblock Zeigertypen verwendet, dann meint man immer den Wert nicht die Adresse:

Code: Alles auswählen

 
var i: ^integer;
begin
   i:= 1; //Neuer Standard: Wert ansprechen nicht die Speicheradresse
  @i:=1; //Speicheradresse ansprechen
end;
 

Dann hätte man auch einheitliche Zeigerbehandlung für alle Arten von Typen.

Ich finde man sollte bei Programmiersprache die zugrunde liegenden Mechanismen nicht verschleiern. Wie das herauskommen kann sieht man bei C++, wenn exzessiv "moderne" Programmiertechniken angewendet werden und die Programme durch hinter den Kulissen verborgene Vorgänge langsam werden. LLVM ist eine gutes Beispiel.
Wie würden Pointer auf Pointer notiert?
Man könnte auch bei Objecterstellung auf Heap, Kontruktionen wie:
MyClass:=TMyClass.Create(xyz);
verzichten, und New verwenden, wie bei Variablen:
New(MyClass, Create(xyz));

Das wäre große Vereinfachung für die Sprache, man könnte Hunderte von Seiten aus Programmierhandbüchern streichen. :D

New() und Dispose() haben mir bei Borland Objekten nie eingeleuchtet.

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Warf »

Soner hat geschrieben:@warf:
Man kann ja Dereferenzierungsoperators auch entfernen, wie man es bei Klassen getan hat.
Wenn man Speicheradresse ansprechen will, dann kann man es immer noch mit @ tun.


So etwas gibt es doch schon, nennt sich AutoDeref modeswitch

Code: Alles auswählen

{$ModeSwitch AUTODEREF+}
type TTestRec = record
  str: String;
  i: Integer;
end;
 
var
  r: ^TTestRec;
begin
  new(r);
  r.str := 'Hallo Welt';
  r.i := 10;
  dispose(r);
end;


Aber es geht mir vor allem auch um die Typnamen. Eine strikte Trennung der Namen von Klasse und Record mit entsprechender eigenständigen Syntax für beides, macht das lernen natürlich deutlich einfacher. Ich habe bereits ein paar mal objects verwendet, doch ich muss trozdem immer wieder nachschauen wie die Syntax ist, denn so was:

Code: Alles auswählen

Var
  Shape1, Shape2 : PShape;
  Rectangle : PRectangle;
  Square : PSquare;
 
begin
  Shape1 := new (PShape, Init(1, 1, 1, 1) );
  Shape2 := new (PShape, Init(2, 2, 2, 2) );
 
  new (Rectangle, Init(11, 22, 33, 44) );
 
  new(Square);
  Square^.Init(111, 222, 333, 444);
 
//...
dispose(Shape1);
  dispose(Shape2, CleanUp);
 
  Rectangle^.CleanUp;
  dispose(Rectangle);
 
  dispose(Square, CleanUp);

finde ich ist eine super verwirrende Syntax. Da ist das Typ.Create von Klassen doch deutlich intuitiver.

Mal ganz davon abgesehen, dass ich der meinung bin bei Stack objects sollte Konstruktor und Destrukor automatisch aufgerufen werden.

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: Record, Object, Class. Warum nicht nur Object?

Beitrag von mse »

Warf hat geschrieben:Mal ganz davon abgesehen, dass ich der meinung bin bei Stack objects sollte Konstruktor und Destrukor automatisch aufgerufen werden.

Bei Stack-Objekten braucht es weder Konstruktor noch Destruktor. Zur Initialisierung und zum Aufräumen hat MSElang [ini] und [fini]:

Code: Alles auswählen

 
type
 objty = object
  f1: int32;
  f2: int32;
  method init() [ini];
  method cleanup() [fini];
 end;
 
method objty.init();
begin
 f1:= 123;
end;
 
method objty.cleanup();
begin
 exitcode:= f1;
end;
 
var
 obj1: objty; //init() and cleanup() automatically called
 
begin
end.
 

Soner
Beiträge: 623
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Soner »

mse hat geschrieben:..
Ich finde man sollte bei Programmiersprache die zugrunde liegenden Mechanismen nicht verschleiern.
...

Tut das nicht derzeitige Klassenhandhabung, nennt man das jetzt nicht "Compiler-Magic"?
Obwohl ein Klassenvariable ein Zeiger auf eine Speicheradresse ist, wird es ohne "^" verwendet. Beim wechsel auf Delphi hatte mich das am meisten verwirrt, dann habe ich irgendwo von "Compiler magic" gehört.

mse hat geschrieben:..
Wie würden Pointer auf Pointer notiert?
..

Wenn du damit Zuweisung meinst, dann genauso wie normale Variablen. Wenn man auch ein Zeiger auf andere Zeiger setzt, dann wird auch kopiert, nur wenn mann "@"-Operator verwendet, dann wird die Speicheradresse geändert ansonsten wird kopiert, auch bei Klassen:

Code: Alles auswählen

 
var
  x,y: ^integer;
  j,k: TObjectX;
begin
   //speicher holen
   //...
 
   x:=1;
   y:=x; // der Wert von x wird an y zugewiesen/kopiert,
                //wenn vorher für y keine Speicher allokiert war, dann wie gehabt Speicherzugrifffehler .
  @y:=x;  //y Zeigt auf 1 weil x hat den Wert von 1
  @y:=@x; // y zeigt auf die adresse von x
 
  j:= k;    // k  wird kopiert und an j zugewiesen
  @j:=k;  // j zeigt auf k wie derzeitiges Verfahren bei Delphi/Fpc
 


Damit würde Unterscheidung von Klassen, normale Variablen, Zeiger verschwinden.
Im Grunde genommen es ist nichts neues, es wird nur umdefiniert:
- Solange es "@" nicht verwendet wird, auch bei Zeigertypen, wird es immer Wert einer Variable angesprochen.
Da man bei Pascal Variablen vorher definieren muss, weiss doch der Compiler welche Variablen zeiger sind, damit ist sowas Zeiger^ unnötig, weil man meistens den Wert einer Variable anspricht.

mse hat geschrieben:..
New() und Dispose() haben mir bei Borland Objekten nie eingeleuchtet.
..

Wieso, hast du noch nie dynamische Records verwendet?

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Record, Object, Class. Warum nicht nur Object?

Beitrag von Warf »

mse hat geschrieben:
Warf hat geschrieben:Mal ganz davon abgesehen, dass ich der meinung bin bei Stack objects sollte Konstruktor und Destrukor automatisch aufgerufen werden.

Bei Stack-Objekten braucht es weder Konstruktor noch Destruktor. Zur Initialisierung und zum Aufräumen hat MSElang [ini] und [fini]:

Code: Alles auswählen

 
type
 objty = object
  f1: int32;
  f2: int32;
  method init() [ini];
  method cleanup() [fini];
 end;
 
method objty.init();
begin
 f1:= 123;
end;
 
method objty.cleanup();
begin
 exitcode:= f1;
end;
 
var
 obj1: objty; //init() and cleanup() automatically called
 
begin
end.
 


Ja so ists mMn auch gut (Bis auf das ich echt kein Fan von eckigen klammern bin). Du hast generell viele gute Ideen zu MSELang, und die Sprache ist auch interessant, leider stellt es für mich (noch) keine alternative da.

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: Record, Object, Class. Warum nicht nur Object?

Beitrag von mse »

Soner hat geschrieben:
mse hat geschrieben:..
Wie würden Pointer auf Pointer notiert?
..

Wenn du damit Zuweisung meinst, dann genauso wie normale Variablen.

Code: Alles auswählen

 
var
  x,y: ^^integer;
 

Meinte ich.
mse hat geschrieben:..
New() und Dispose() haben mir bei Borland Objekten nie eingeleuchtet.

Wieso, hast du noch nie dynamische Records verwendet?

Mit Objekten scheinen mir constructor() und destructor() eher passend statt new() und dispose().

Antworten