Не буду заниматься анализом или "разжёвыванием".
Просто приведу пример.
Просто, "чтоб вы знали".
Вот такой код:
Хотя "всё очевидно". Смотрим на код:
Почему я это пишу?
Просто потому, что я видел людей, которые сильно удивляются этому.
Для тех кто хочет "откомментировать" скажу - "я не из их числа".
Хотя... И сам "нажирался"...
Просто приведу пример.
Просто, "чтоб вы знали".
Вот такой код:
type
ISomeInterface = interface
procedure SomeMethod;
end;//
TA = class(TObject, ISomeInterface {IUnknown тут СПЕЦИАЛЬНО опущен})
function _AddRef: Integer;
function _Release: Integer;
function QueryInterface(const anID: TGUID; out anObj): hResult; virtual;
procedure SomeMethod;
end;//TA
TB = class(TA)
function QueryInterface(const anID: TGUID; out anObj): hResult; override;
end;//TB
TC = class(TIntefacedObject, ISomeInterface)
procedure SomeMethod;
end;//TC
...
function TA._AddRef: Integer;
begin
Result := -1;
end;
function TA._Release: Integer;
begin
Result := -1;
end;
function TA.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
if Self.GetInterface(anID, anObj) then
Result := S_Ok
else
Result := E_NoInterface;
end;
procedure TA.SomeMethod;
begin
Write('A');
end;
function TB.QueryInterface(const anID: TGUID; out anObj): hResult;
begin
if IsEqualGUID(anID, ISomeInterface) then
begin
Result := S_Ok;
ISomeInterface(Obj) := TC.Create;
end//IsEqualGUID(anID, ISomeInterface)
else
Result := inherited QueryInterface(anID, Obj);
end;
procedure TC.SomeMethod;
begin
Write('C');
end;
...
var
l_A : ISomeInterface;
l_B : ISomeInterface;
begin
A := TA.Create;
B := TB.Create;
if not Supports(A, ISomeInterface, l_A) then
Assert(false);
l_A.SomeMethod; // - в консоли видим A
if not Supports(B, ISomeInterface, l_B) then
Assert(false);
l_B.SomeMethod; // - в консоли видим A, а "хотелось бы" - C
end;
Хотя "всё очевидно". Смотрим на код:
function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean;
var
LUnknown: IUnknown;
begin
Result := (Instance <> nil) and
((Instance.GetInterface(IUnknown, LUnknown) and Supports(LUnknown, IID, Intf)) or
Instance.GetInterface(IID, Intf));
end;
Почему я это пишу?
Просто потому, что я видел людей, которые сильно удивляются этому.
Для тех кто хочет "откомментировать" скажу - "я не из их числа".
Хотя... И сам "нажирался"...
Извините но я не понимаю как мы ожидаем С. Если это метод класса TC. Мы же даже объект не создаем ?
ОтветитьУдалитьОтветил тут - http://programmingmindstream.blogspot.ru/2014/04/supports_4.html
ОтветитьУдалить