Не буду заниматься анализом или "разжёвыванием".
Просто приведу пример.
Просто, "чтоб вы знали".
Вот такой код:
Хотя "всё очевидно". Смотрим на код:
Почему я это пишу?
Просто потому, что я видел людей, которые сильно удивляются этому.
Для тех кто хочет "откомментировать" скажу - "я не из их числа".
Хотя... И сам "нажирался"...
Просто приведу пример.
Просто, "чтоб вы знали".
Вот такой код:
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
ОтветитьУдалить