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