Irgendwas hab ich falsch verstanden und es hängt wohl mit dem Referenzzähler zusammen.
Mein Testcode:
Delphi-Quellcode:
unit Main;
interface
uses
SysUtils, Forms, Dialogs, StdCtrls, Classes, Controls;
type
ISquare =
interface(IInterface)
['
{4F30FDE5-9C8C-4F34-A828-FA32B1C0DA3F}']
procedure Square;
end;
TInt =
class(TInterfacedObject, ISquare)
private
FInt: Integer;
public
procedure Square;
property Number: Integer
read FInt
write FInt;
end;
TFloat =
class(TInterfacedObject, ISquare)
private
FFloat: Single;
public
procedure Square;
property Number: Single
read FFloat
write FFloat;
end;
TMainForm =
class(TForm)
Button: TButton;
procedure ButtonClick(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
procedure TInt.Square;
begin
FInt:= FInt * FInt;
end;
procedure TFloat.Square;
begin
FFloat:= FFloat * FFloat;
end;
procedure SquareIt(aNumber: ISquare);
//Fehler ohne const, mit kein Fehler
begin
aNumber.Square;
end;
procedure TMainForm.ButtonClick(Sender: TObject);
var
aInt: TInt;
aFloat: TFloat;
MyInterface: ISquare;
begin
aInt:= TInt.Create;
//MyInterface:= aInt; //Interface Referenz Counter geht hoch
aFloat:= TFloat.Create;
aInt.Number:= 5;
//MyInterface.Square;
MyInterface:=
nil;
//Zähler geht wieder runter
aFloat.Number:= 5;
aInt.Square;
aFloat.Square;
ShowMessage(IntToStr(aInt.Number));
ShowMessage(FloatToStr(aFloat.Number));
//SquareIt(aInt); //während der Aufrufe geht der Zähler auch hoch
//SquareIt(Float);
ShowMessage(IntToStr(aInt.Number));
ShowMessage(FloatToStr(aFloat.Number));
aInt.Free;
aFloat.Free;
end;
end.
Solange ich keine der auskommentierten Zeilen aufrufe, funktioniert das Ganze. Bei SquareIt dagegen:
Code:
---------------------------
Benachrichtigung über Debugger-
Exception
---------------------------
Im Projekt InterfaceTest.exe ist eine
Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 00403864 in Modul 'InterfaceTest.exe'. Lesen von Adresse FFFFFFFC' aufgetreten.
---------------------------
Anhalten Fortsetzen Hilfe
---------------------------
Währernd die Zuweisung auf MyInterface produziert (exakt) die selbe Meldung. Wo liegt mein Denkfehler? Wenn ich stattdessen
procedure SquareIt(const aNumber: ISquare);
schreibe, dann funktioniert das Ganze. Daraus folger ich mal das der Fehler etwas mit dem Kopieren einer neuen Referenz zu tun hat und das dies wohl ohne const passiert. Wie genau sollten Interfaces verwendet werden? Die Möglichkeit solcher Konstruktionen wäre ja sonst recht sinnlos?
Man kann einen Barbier definieren als einen, der alle diejenigen rasiert, und nur diejenigen, die sich nicht selbst rasieren.
Rasiert sich der Barbier?