Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как запретить авто удаление наследнику TInterfacedObject?


Страницы:   1 2

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)
> Ошибок не насажал?

Так нормально.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо