Operator Overloading für Klassen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Heinrich Wolf
Beiträge: 323
Registriert: Di 12. Apr 2011, 13:21
OS, Lazarus, FPC: WinXP + VMWare Player mit Fedora14, L 1.1, FPC 2.7.1
CPU-Target: 1core 1,8GHz 32Bit
Wohnort: Fürth
Kontaktdaten:

Operator Overloading für Klassen

Beitrag von Heinrich Wolf »

Hallo,

kann fpc mehr als Delphi? Ich glaube nicht. In Delphi ohne DotNet gibt es Operator Overloading nur für Records, aber nicht für Klassen und die Deklaration heißt dennoch Class Operator. Ich hab mal folgendes Programm mit Lazarus getestet und dabei folgende Ausgabe gekriegt. Ein Destruktor Aufruf zu wenig!

Code: Alles auswählen

Create
Create
Create
Destroy
Destroy
 
program Constr;
 
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this };
 
{$R *.res}
 
type
  tMyClass    = class
    Constructor Create;
    Destructor  Destroy; override;
  end;
 
var
  a, b : tMyClass;
 
Constructor tMyClass.Create;
  begin
    inherited;
    writeln('Create');
  end;
 
Destructor  tMyClass.Destroy;
  begin
    writeln('Destroy');
    inherited;
  end;
 
Operator +(a, b : tMyClass) : tMyClass;
  begin
    Result := tMyClass.Create;
  end;
 
begin
  a := tMyClass.Create;
  b := tMyClass.Create;
  a := a + b;
  a.Free;
  b.Free;
  readln;
end.
Zuletzt geändert von Lori am Fr 6. Mai 2011, 23:25, insgesamt 1-mal geändert.
Grund: Highlighter

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2809
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Operator Overloading für Klassen

Beitrag von m.fuchs »

Heinrich Wolf hat geschrieben:Ich hab mal folgendes Programm mit Lazarus getestet und dabei folgende Ausgabe gekriegt. Ein Destruktor Aufruf zu wenig!

Create
Create
Create
Destroy
Destroy
Drei mal Create aufgerufen, zweimal Destroy aufgerufen.
Heinrich Wolf hat geschrieben:

Code: Alles auswählen

begin
  a := tMyClass.Create;
  b := tMyClass.Create;
  a := a + b;
  a.Free;
  b.Free;
  readln;
end.
Drei mal Create aufgerufen, zweimal Destroy aufgerufen. Passt.

Was fehlt dir denn jetzt? Dass die allererste Instanz von tMyClass nicht vernichtet wurde? Tja, dazu muss man irgendwie den Destruktor aufrufen.

mfg
Micha
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Operator Overloading für Klassen

Beitrag von Eclipticon »

m.fuchs hat geschrieben:Was fehlt dir denn jetzt? Dass die allererste Instanz von tMyClass nicht vernichtet wurde? Tja, dazu muss man irgendwie den Destruktor aufrufen.
Ja, wenn man den nach der Addition mit dem overloaded operator noch faende ;-)

Die einzige saubere Loesung ist wohl eine dritte Instanz, da es wohl kaum intuitiv ist, wenn in einem overloaded operator Instanzen zerstoert werden ...

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2809
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Operator Overloading für Klassen

Beitrag von m.fuchs »

Ich muss noch mal klugsch***en:
Eclipticon hat geschrieben:Die einzige saubere Loesung ist wohl eine dritte Instanz, da es wohl kaum intuitiv ist, wenn in einem overloaded operator Instanzen zerstoert werden ...
Das sind sogar drei Instanzen, aber nur zwei Referenzen. Und der Operator zerstört keine Instanz (und auch keine Referenz).

Sorry, aber bei Verwechselungen in der Benamung kann man schnell in Steves Küche kommen.

mfg
Micha
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Eclipticon
Beiträge: 292
Registriert: Sa 5. Feb 2011, 20:38
OS, Lazarus, FPC: Windows XP VirtualBox (FPC 2.6.4, Laz 1.2.4)
CPU-Target: 32Bit
Wohnort: Wien

Re: Operator Overloading für Klassen

Beitrag von Eclipticon »

m.fuchs hat geschrieben:Und der Operator zerstört keine Instanz (und auch keine Referenz).
Nein, tut er nicht ... aber man sollte IMHO auch nicht auf die Idee kommen, solche Dinge in den Operator zu packen. (Koennte man aber, da hier die originale Instanz noch benoetigt wird, aber das gleichzeitig das einzige Stueck Code ist, in dem die Referenz ;-) auf die originale Instanz noch bekannt ist.)

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Operator Overloading für Klassen

Beitrag von theo »

Oder so: ;-)

Code: Alles auswählen

...
type
iMyClass=interface
end;
 
tMyClass = class(TInterfacedObject,iMyClass)
Constructor Create;
Destructor Destroy; override;
end;
 
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
Constructor tMyClass.Create;
begin
inherited;
writeln('Create');
end;
 
Destructor tMyClass.Destroy;
begin
writeln('Destroy');
inherited;
end;
 
Operator +(a, b : iMyClass) : iMyClass;
begin
Result := tMyClass.Create;
end;
 
 
procedure TForm1.Button1Click(Sender: TObject);
var a, b : iMyClass;
begin
a := tMyClass.Create;
b := tMyClass.Create;
a := a + b;
end;

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2809
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Operator Overloading für Klassen

Beitrag von m.fuchs »

Das ist auch etwas, was ich nie verstanden habe. Bisher waren Interfaces immer dafür da, dass man eine bestimmte Schnittstelle definiert und diese dann implementiert werden kann.

In FPC kommt noch (teilweise) die Möglichkeit der Referenzzählung dazu. Finde ich irgendwie seltsam. Das hat wohl Gründe in der Nutzung von COM?


mfg
Micha
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Patito
Beiträge: 203
Registriert: Di 22. Sep 2009, 13:08
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Operator Overloading für Klassen

Beitrag von Patito »

m.fuchs hat geschrieben:Das ist auch etwas, was ich nie verstanden habe. Bisher waren Interfaces immer dafür da, dass man eine bestimmte Schnittstelle definiert und diese dann implementiert werden kann.

In FPC kommt noch (teilweise) die Möglichkeit der Referenzzählung dazu. Finde ich irgendwie seltsam. Das hat wohl Gründe in der Nutzung von COM?

mfg
Micha
Nun ja, mit Interfaces und Referenzzählung verhält sich so:

Bei Borland haben die Entwickler damals den Design-Fehler gemacht Interfaces immer fest mit Referenzzählung zu verkoppeln.
Das lag wohl daran, dass sie als Anwendung nur an COM gedacht haben, und dabei wohl übersehen haben, dass es für viele Objekte Schwachsinn ist sie über Referenzzählung zu verwalten.

Seither muß man sich in Delphi bei Interfaces immer mit Referenzzählung herumschlagen - und es gibt dort nichts anderes.
Bei FPC waren die Entwickler etwas schlauer, und dort gibt es die Corba-Interfaces ohne Referenzählung.

Von Delphi her haben sich die Leute aber eben an den ganzen Referenzzähl-Unfug gewöhnt
... und jetzt gibt es eben so tricky-Anwendungsfälle, in denen die Leute Interfaces für ihr Memory-Management verwenden...
:roll:

Heinrich Wolf
Beiträge: 323
Registriert: Di 12. Apr 2011, 13:21
OS, Lazarus, FPC: WinXP + VMWare Player mit Fedora14, L 1.1, FPC 2.7.1
CPU-Target: 1core 1,8GHz 32Bit
Wohnort: Fürth
Kontaktdaten:

Re: Operator Overloading für Klassen

Beitrag von Heinrich Wolf »

theo hat geschrieben:Oder so: ;-)
Das ist ja noch schlimmer!

Create
Create
Create
Destroy

Heinrich Wolf
Beiträge: 323
Registriert: Di 12. Apr 2011, 13:21
OS, Lazarus, FPC: WinXP + VMWare Player mit Fedora14, L 1.1, FPC 2.7.1
CPU-Target: 1core 1,8GHz 32Bit
Wohnort: Fürth
Kontaktdaten:

Re: Operator Overloading für Klassen

Beitrag von Heinrich Wolf »

Heinrich Wolf hat geschrieben:
theo hat geschrieben:Oder so: ;-)
Das ist ja noch schlimmer!

Create
Create
Create
Destroy
Entschuldigung!
Es ist völlig ok.

So hatte ich's in der Konsole Anwendung getestet:

Code: Alles auswählen

var a, b : iMyClass;
 
begin
  a := tMyClass.Create;
  b := tMyClass.Create;
  a := a + b;
  readln;
end.
und so gehört es getestet:

Code: Alles auswählen

procedure Test;
  var a, b : iMyClass;
  begin
    a := tMyClass.Create;
    b := tMyClass.Create;
    a := a + b;
  end;
 
begin
  Test;
  readln;
end.      
 
Create
Create
Create
Destroy
Destroy
Destroy
Zuletzt geändert von Lori am Fr 6. Mai 2011, 23:26, insgesamt 1-mal geändert.
Grund: Bitte den Highlighter benutzen

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2809
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Operator Overloading für Klassen

Beitrag von m.fuchs »

@Heinrich Wolf: Was war denn nun aber dein ursprüngliches Problem. Habs noch net so ganz verstanden.
Oder einfach die Tatsache dass es keinen GarbageCollector gibt?

Wer sowas braucht/will soll .NET entwickeln :wink:

SCNR
Micha
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Operator Overloading für Klassen

Beitrag von MAC »

Wie wärs damit ?

Code: Alles auswählen

Operator +(a, b : iMyClass) : iMyClass;
begin
Result := tMyClass.Create;
a.Free
b.Free
end;
 
und dann dementsprechend:
 
a := tMyClass.Create;
b := tMyClass.Create;
a := a + b;
a.Free;
problematisch ist, das man bei operator + nicht weis wo das ergebnis gespeichert wird. Am besten sollte man

Code: Alles auswählen

C := a +b //verwenden , dann geht auch das alte
Übrigens . mit klich auf Highlighter - kann man eine Code-Box erstellen.
Das lässt sich dann schneller/besser lesen...

Code: Alles auswählen

Signatur := nil;

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: Operator Overloading für Klassen

Beitrag von theo »

MAC hat geschrieben:Wie wärs damit ?
Dafür braucht's aber keine Interfaces.
Die Objekte freizugeben beim Anwenden des Operators halte ich für unanständig.

Heinrich Wolf
Beiträge: 323
Registriert: Di 12. Apr 2011, 13:21
OS, Lazarus, FPC: WinXP + VMWare Player mit Fedora14, L 1.1, FPC 2.7.1
CPU-Target: 1core 1,8GHz 32Bit
Wohnort: Fürth
Kontaktdaten:

Re: Operator Overloading für Klassen

Beitrag von Heinrich Wolf »

@m.fuchs
Ein Problem hab ich mit dem operator overloading nicht. Es interessiert mich nur theoretischer Art.

@MAC
Ich hab gesehen, dass Code in der Code Box mit Syntax Highlighting und Einrücken angezeigt wird. Aber ich mag's trotzdem nicht, weil ich nicht geschafft hab, den Code sauber aus dem Internet Explorer zu kopieren und in Lazarus einzufügen. Ich hab nur eine Bandwurmzeile gekriegt.

Gruß
Heiner

Antworten