![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как запретить авто удаление наследнику TInterfacedObject?
Kolan © (2007-12-04 14:31:00)Здравствуйте,
Был у меня синглетон наследник TObject. Понадобилось чтобы он поддерживал интерфейс, сделал наследником TInterfacedObject. Теперь при при передаче его как интерфейса в процедуру, он, по всей видимости удаляется по её завершении.
Вопрос как корректно предотвратить авто удаление?
Ins (2007-12-05 16:56:00) [1]stdcall не везде
Kolan (2007-12-05 16:55:00) [2]stdcall; забыл написать Вопрос снят
Kolan (2007-12-05 16:43:00) [3]Продолжение вопроса.
Похожий момент, но только теперь у синглетона уже есть предок.
TSystemController = class(TIndexedDomainListObjectListner, IPatientSearchVisitor)
Следовательно я сам добавил
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult;
Вот ругается:
[Error] Declaration of 'QueryInterface' differs from declaration in interface 'IPatientSearchVisitor'
Где
IPatientSearchVisitor = interface
['{E977F349-6656-4416-B407-BAB207CBE051}']
function GetPatients(PatientsRequest: IPatientsRequest): TDataSet;
end;
Как это понять?
Kolan (2007-12-05 10:50:00) [4]Удалено модератором
Примечание: Жаргон смени
Ins (2007-12-05 10:41:00) [5]
> А QueryInterface в этом случае просто скопировать? Откуда?
Скопировать, причем все равно, у TInterfacedPersistent или TInterfacedObject, они одинаковы. Их вызов просто сводится к вызову GetInterface:
function TInterfacedObject.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function TInterfacedPersistent.QueryInterface(const IID: TGUID;
out Obj): HResult;
const
E_NOINTERFACE = HResult($80004002);
begin
if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;
end;
Kolan (2007-12-05 10:28:00) [6]> Все хорошо, но я все-таки до конца не понимаю смысл тщательного
> измерения дли шага у мерина, которого ведут на живодерню.
Мы вашу феню не коцаем :)
Игорь Шевченко (2007-12-05 10:08:00) [7]Все хорошо, но я все-таки до конца не понимаю смысл тщательного измерения дли шага у мерина, которого ведут на живодерню.
oxffff (2007-12-05 10:07:00) [8]
> oxffff © (05.12.07 10:04) [27]
Главное не перекрывать function TPersistent.GetOwner: TPersistent;dynamic;
oxffff (2007-12-05 10:04:00) [9]
> Kolan © (05.12.07 09:55) [26]
Если наследуешься от TInterfacedPersistent, то тогда в твоем случае ничего делать не нужно.
Kolan (2007-12-05 09:55:00) [10]Зачем мне нужен AClass?
Сейчас отнаследовлся от TInterfacedPersistent, собстренную реализацию _AddRef и _Release закоментил, работает. Так нормаль сделать?
oxffff (2007-12-05 09:50:00) [11]AClass=class(Tobject)
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
BClass=class(AClass,IVisitor)
function Foo: Integer;
end;
Если необходима работа оператора AS, тогда
AClass=class(Tobject,Iinterface)
Kolan (2007-12-05 09:04:00) [12]> Что у тебя за задача?
Был синглетон. У него была операцияfuncton Foo: Integer;
Есть совершенно независимый модуль, в котором есть класс и в нем операцияprocedure DoSmth(Visitor: IVisitor);
Где
IVisitor = interface
functon Foo: Integer;
end;
В синглетоне у же естьFooи она делает что что надо, осталось только сделать, чтобы синглетон поддкрживалIVisitor.
Вот сделать чтобы поддерживал(чобы передать его(синглетон) в DoSmth) и есть задача, в остальном он должен работать так, как и работал.
oxffff (2007-12-05 08:48:00) [13]
> Kolan © (05.12.07 08:38) [22]
Решений может быть несколько.
Что у тебя за задача?
Kolan (2007-12-05 08:38:00) [14]> Зачем наследоваться от TInterfacedObject? Чтобы при случае
> добраться до старой версии _Release, и таки грохнуть объект?
Нет, ошибка это.
Так в итоге как сделать лучьше?
Отнаследоватьсяот TInterfacedPersistent.
Или
TObject, IInterface
А QueryInterface в этом случае просто скопировать? Откуда?
Ins (2007-12-04 23:35:00) [15]А я в таких случаях обычно наследуюсь от TInterfacedPersistent, т.к. TComponent на мой взгляд несколько избыточен. Или можно, как уже сказали, написать свой класс = class(TObject, IInterface) и самому реализовать методы _AddRef и _Release, просто возвращая в них -1.
Джо (2007-12-04 21:54:00) [16]А, точно, я сразу и не заметил, что от TInterfacedObject наследуемся.
DrPass (2007-12-04 21:38:00) [17]
> Унаследовался от TInterfacedObject'а
>
> Сделал так:
>
> function TStartUpController._AddRef: Integer;
> begin
> Result := —1; {No ref countiong}
> end;
>
> function TStartUpController._Release: Integer;
> begin
> Result := —1; {No ref countiong}
> end;
>
> Ошибок не насажал?
Немного насажал. Зачем наследоваться от TInterfacedObject? Чтобы при случае добраться до старой версии _Release, и таки грохнуть объект?
oxffff (2007-12-04 19:40:00) [18]
> Джо © (04.12.07 15:36) [16]
> > [13] Kolan © (04.12.07 15:33)
> > Ошибок не насажал?
>
> Так нормально.
И все же потенциально ошибка может возникнуть.
TKolanClass=class(TInterfacedObject,Iunknown)
public
function _AddRef: Integer;stdcall;
function _Release: Integer;stdcall;
destructor destroy;override;
end;
{ TKolanClass }
destructor TKolanClass.destroy;
begin
Showmessage('Object is under destruction');
inherited;
end;
function TKolanClass._AddRef: Integer;
begin
result:=-1;
end;
function TKolanClass._Release: Integer;
begin
result:=-1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var KolanClass:TKolanClass;
a:IUnknown;
c:TinterfacedObject;
begin
KolanClass:=TKolanClass.Create;
a:=KolanClass;
a:=nil;
a:=KolanClass as Iunknown;
a:=nil;
c:=KolanClass;
a:=c; //_Addref от TInterfacedObject
a:=nil; // _Release от TInterfacedObject
{
Здесь объект KolanClass уже разрушен.
}
end;
Kolan (2007-12-04 15:58:00) [19]> Так нормально.
Ок
> Да не видно
Сенкс.
> После создания экземпляра, просто вызови _AddRef и никто
> его не убъет кроме тебя самого.
Благодарю вопрос решен :)
Джо (2007-12-04 15:36:00) [20]> [13] Kolan © (04.12.07 15:33)
> Ошибок не насажал?
Так нормально.