Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#569

AW: Was nervt euch so, wärend der Programmierung oder so allgemein

  Alt 2. Nov 2011, 20:57
Hi Stevie,

seit man aber Interfaces wieder in Objekte zurückcasten kann (IInterfaceComponentReference sei Dank ... die haben mir meine Idee geklaut ),
ist dieses nicht mehr sicher, denn wenn man dann auf das ältere Klasse castet und dann wieder in ein Interface, dann wird das Interface des Vorfahren und nicht das Neue verwendet.

Und IInterfaceComponentReference zu überschreiben hatte keinerlei Wirkung, sonst hätt' ich da einfach NIL zurückgegeben.

Delphi-Quellcode:
type
  TMyClass1 = class(TObject, IInterface)
    function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;

  TMyClass2 = class(TMyClass1, IInterface)
    function QueryInterface(const IID: TGUID; out Obj): HResult; override; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i1, i2, i3, i4, i5, i6: IInterface;
  o5: TMyClass1;
  o6: TMyClass2;
begin
  Memo1.Lines.Add('');
  Memo1.Lines.Add('o6 := TMyClass2.Create / i6 := TMyClass2(o6) as IInterface');
  o6 := TMyClass2.Create;
  i6 := o6 as IInterface;
  i6._AddRef;

  Memo1.Lines.Add('');
  Memo1.Lines.Add('o5 := TMyClass2.Create; / i5 := TMyClass1(o5) as IInterface;');
  o5 := TMyClass2.Create;
  i5 := o5 as IInterface;
  i5._AddRef;

  Memo1.Lines.Add('');
  Memo1.Lines.Add('i1 := TMyClass1.Create;');
  i1 := TMyClass1.Create;
  i1._AddRef;

  Memo1.Lines.Add('');
  Memo1.Lines.Add('i2 := TMyClass2.Create;');
  i2 := TMyClass2.Create;
  i2._AddRef;

  Memo1.Lines.Add('');
  Memo1.Lines.Add('i3 := TMyClass2(i2) as TMyClass2;');
  i3 := i2 as TMyClass2;
  i3._AddRef;

  Memo1.Lines.Add('');
  Memo1.Lines.Add('i4 := TMyClass2(i2) as TMyClass1;');
  i4 := i2 as TMyClass1;
  i4._AddRef;

  Memo1.Lines.Add('');
end;

{ TMyClass1 }

function TMyClass1.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  Form1.Memo1.Lines.Add('TMyClass1.QueryInterface');
  if GetInterface(IID, Obj) then
    Result := 0
  else
    Result := E_NOINTERFACE;
end;

function TMyClass1._AddRef: Integer;
begin
  Form1.Memo1.Lines.Add('TMyClass1._AddRef');
end;

function TMyClass1._Release: Integer;
begin
  Form1.Memo1.Lines.Add('TMyClass1._Release');
end;

{ TMyClass2 }

function TMyClass2.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  Form1.Memo1.Lines.Add('TMyClass2.QueryInterface');
  if GetInterface(IID, Obj) then
    Result := 0
  else
    Result := E_NOINTERFACE;
end;

function TMyClass2._AddRef: Integer;
begin
  Form1.Memo1.Lines.Add('TMyClass2._AddRef');
end;

function TMyClass2._Release: Integer;
begin
  Form1.Memo1.Lines.Add('TMyClass2._Release');
end;

end.




o6 := TMyClass2.Create / i6 := TMyClass2(o6) as IInterface
TMyClass2.QueryInterface
TMyClass2._AddRef
TMyClass2._AddRef

o5 := TMyClass2.Create; / i5 := TMyClass1(o5) as IInterface;
TMyClass1.QueryInterface // ist QueryInterface nicht virtual kommt hier TMyClass1.QueryInterface rause
TMyClass2._AddRef
TMyClass2._AddRef

i1 := TMyClass1.Create;
TMyClass1._AddRef
TMyClass1._AddRef

i2 := TMyClass2.Create;
TMyClass2._AddRef
TMyClass2._AddRef

i3 := TMyClass2(i2) as TMyClass2;
TMyClass2.QueryInterface
TMyClass2._AddRef
TMyClass2._AddRef

i4 := TMyClass2(i2) as TMyClass1;
TMyClass2.QueryInterface
TMyClass1._AddRef
TMyClass1._AddRef

TMyClass2._Release
TMyClass2._Release
TMyClass1._Release
TMyClass2._Release
TMyClass2._Release
TMyClass1._Release
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.