Форум: "Начинающим";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];
Вниз
Как запретить авто удаление наследнику TInterfacedObject? Найти похожие ветки
← →
Kolan © (2007-12-04 14:31) [0]Здравствуйте,
Был у меня синглетон наследник TObject. Понадобилось чтобы он поддерживал интерфейс, сделал наследником TInterfacedObject. Теперь при при передаче его как интерфейса в процедуру, он, по всей видимости удаляется по её завершении.
Вопрос как корректно предотвратить авто удаление?
← →
Skyle © (2007-12-04 14:36) [1]Для начала корректно с ним работать как с интерфейсом.
Можно ещё плюнуть на TInterfacedObject и самостоятельно реализовать методы IUnknown.
← →
Kolan © (2007-12-04 14:38) [2]> Для начала корректно с ним работать как с интерфейсом.
Для начала корректно с ним работать как с интерфейсом.
Как интерфейс он мне нужен в одном месте, которое я добавил только что. Во всех остальных надо оставить старое поведение синглетона.
← →
MetalFan © (2007-12-04 14:46) [3]
> Как интерфейс он мне нужен в одном месте, которое я добавил
> только что.
> плюнуть на TInterfacedObject и самостоятельно реализовать
> методы IUnknown.
;)
← →
Kolan © (2007-12-04 14:48) [4]Вот у меня есть коммен Egи по поводу сабжа.
[3] Ega23 © (09.11.07 10:34)
> И скопипастиьть их из TInterfacedObject, так?
Это уж как тебе надо. Лично я внутри _AddRef и _Release счётчик сылок в —1 держу, если не хочу, чтобы объект автоматом разрушилсо.
+
[3] MetalFan © (04.12.07 14:46)
> ;)
А как это(сылок в —1 держу) сдеать правильно?
← →
Kolan © (2007-12-04 14:53) [5]Я понимаю вроде что RefCount := —1 но опасаюсь что это не все что надо…
← →
Kolan © (2007-12-04 15:15) [6]Проблемма в том, что полсе того как я добавил поддержку интерфейса стало вылетать ав при удалении синглетона:
initialization
finalization
StartUpController.Free;
Более нигде он не разрушается.
← →
Skyle © (2007-12-04 15:19) [7]
> Kolan © (04.12.07 15:15) [6]
> Более нигде он не разрушается.
Тобой.
← →
Reindeer Moss Eater © (2007-12-04 15:21) [8]_addref в качестве подпорки. Если неохота разбираться в отличиях объектных и интерфейсных ссылок.
← →
Kolan © (2007-12-04 15:22) [9]> Тобой.
Мной лично нет. Следовательно все из-за того, что я его передаю в процедуру:function TUserLoginForm.ShowLoginDialog(ALogin: string;
ALoginVisitor: ILoginVisitor): Boolean;
begin
if Assigned(ALoginVisitor) then
begin
FLoginVisitor := ALoginVisitor;
UserNameEdit.Text := ALogin;
Result := inherited ShowModal = mrOk;
end;
end;
Где FLoginVisitor поле класса. А сам этот класс(TUserLoginForm) уничтожается и видимо уничтожает и FLoginVisitor… Как предотвртить?function TStartUpController._AddRef: Integer;
begin
FRefCount := —1;
end;
function TStartUpController._Release: Integer;
begin
FRefCount := —1;
end;
Меняет ав на инвалид поинтер оперэйшн …
← →
Игорь Шевченко © (2007-12-04 15:22) [10]Унаследуй не от TInterfacedObject, а от TComponent
← →
Kolan © (2007-12-04 15:23) [11]
> Если неохота разбираться в отличиях объектных и интерфейсных
> ссылок.
Как я понимаю са интр ссылками следят и если счетчик становится 0, то объект уничтожается, но как корректно предотвратьть это не пойму.
← →
Kolan © (2007-12-04 15:26) [12]
> Унаследуй не от TInterfacedObject, а от TComponent
Да так корректно все, благодарю — решение.
function TComponent._AddRef: Integer;
begin
if FVCLComObject = nil then
Result := —1 // —1 indicates no reference counting is taking place
else
Result := IVCLComObject(FVCLComObject)._AddRef;
end;
А, Result := —1;…
← →
Kolan © (2007-12-04 15:33) [13]Унаследовался от TInterfacedObject"а
Сделал так:
function TStartUpController._AddRef: Integer;
begin
Result := —1; {No ref countiong}
end;
function TStartUpController._Release: Integer;
begin
Result := —1; {No ref countiong}
end;
Ошибок не насажал?
← →
Reindeer Moss Eater © (2007-12-04 15:34) [14]После создания экземпляра, просто вызови _AddRef и никто его не убъет кроме тебя самого.
← →
Skyle © (2007-12-04 15:35) [15]> Kolan © (04.12.07 15:33) [13]
Да не видно
← →
Джо © (2007-12-04 15:36) [16]> [13] Kolan © (04.12.07 15:33)
> Ошибок не насажал?
Так нормально.
← →
Kolan © (2007-12-04 15:58) [17]> Так нормально.
Ок
> Да не видно
Сенкс.
> После создания экземпляра, просто вызови _AddRef и никто
> его не убъет кроме тебя самого.
Благодарю вопрос решен :)
← →
oxffff © (2007-12-04 19:40) [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;
← →
DrPass © (2007-12-04 21:38) [19]
> Унаследовался от 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, и таки грохнуть объект?
← →
Джо © (2007-12-04 21:54) [20]А, точно, я сразу и не заметил, что от TInterfacedObject наследуемся.
← →
Ins © (2007-12-04 23:35) [21]А я в таких случаях обычно наследуюсь от TInterfacedPersistent, т.к. TComponent на мой взгляд несколько избыточен. Или можно, как уже сказали, написать свой класс = class(TObject, IInterface) и самому реализовать методы _AddRef и _Release, просто возвращая в них -1.
← →
Kolan © (2007-12-05 08:38) [22]> Зачем наследоваться от TInterfacedObject? Чтобы при случае
> добраться до старой версии _Release, и таки грохнуть объект?
Нет, ошибка это.
Так в итоге как сделать лучьше?
Отнаследоватьсяот TInterfacedPersistent.
Или
TObject, IInterface
А QueryInterface в этом случае просто скопировать? Откуда?
← →
oxffff © (2007-12-05 08:48) [23]
> Kolan © (05.12.07 08:38) [22]
Решений может быть несколько.
Что у тебя за задача?
← →
Kolan © (2007-12-05 09:04) [24]> Что у тебя за задача?
Был синглетон. У него была операцияfuncton Foo: Integer;
Есть совершенно независимый модуль, в котором есть класс и в нем операцияprocedure DoSmth(Visitor: IVisitor);
ГдеIVisitor = interface
functon Foo: Integer;
end;
В синглетоне у же естьFoo
и она делает что что надо, осталось только сделать, чтобы синглетон поддкрживалIVisitor
.
Вот сделать чтобы поддерживал(чобы передать его(синглетон) в DoSmth) — и есть задача, в остальном он должен работать так, как и работал.
← →
oxffff © (2007-12-05 09:50) [25]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:55) [26]Зачем мне нужен AClass?
Сейчас отнаследовлся от TInterfacedPersistent, собстренную реализацию _AddRef и _Release закоментил, работает. Так нормаль сделать?
← →
oxffff © (2007-12-05 10:04) [27]
> Kolan © (05.12.07 09:55) [26]
Если наследуешься от TInterfacedPersistent, то тогда в твоем случае ничего делать не нужно.
← →
oxffff © (2007-12-05 10:07) [28]
> oxffff © (05.12.07 10:04) [27]
Главное не перекрывать function TPersistent.GetOwner: TPersistent;dynamic;
← →
Игорь Шевченко © (2007-12-05 10:08) [29]Все хорошо, но я все-таки до конца не понимаю смысл тщательного измерения дли шага у мерина, которого ведут на живодерню.
← →
Kolan © (2007-12-05 10:28) [30]> Все хорошо, но я все-таки до конца не понимаю смысл тщательного
> измерения дли шага у мерина, которого ведут на живодерню.
Мы вашу феню не коцаем :)
← →
Ins © (2007-12-05 10:41) [31]
> А 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:50) [32]Удалено модератором
Примечание: Жаргон смени
← →
Kolan © (2007-12-05 16:43) [33]Продолжение вопроса.
Похожий момент, но только теперь у синглетона уже есть предок.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 16:55) [34]stdcall; забыл написать… Вопрос снят
← →
Ins © (2007-12-05 16:56) [35]stdcall не везде
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.007 c