Einzelnen Beitrag anzeigen

Cyf

Registriert seit: 30. Mai 2008
407 Beiträge
 
Lazarus
 
#1

Verständnisfrage zur Benutzung von Interfaces

  Alt 24. Jul 2009, 01:55
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?
  Mit Zitat antworten Zitat