Форум: "Основная";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
ВнизХрень с интерфейсом Найти похожие ветки
← →
MgFox (2004-12-30 10:20) [0]Есть Интерфейс типа:
IMyIntf = interface
procedure callMe;
end;
класс к которому сий интерфейс привинченTMyClass=class(TObject,IMyIntf) ...
А экземпляр этого класса хранится не в обычной переменной я в переменной типа Pointer валяется на него ссылка.
И соответственно когда я пытаюсь обратиться к методу интерфейса
через указатель на объектIMyIntf(ptr).callMe;
в ответ получаю Exception типа "Access violation ..."
Сообственно вопрос: как с этой хренью бороться ?
← →
Sandman25 © (2004-12-30 10:22) [1](TMyClass(prt) as IMyIntf).Callme
А вообще лучше хранить в виде IMyIntF, а не pointer
← →
Palladin © (2004-12-30 10:25) [2]IMyIntf(ptr^).callMe; только зачем этот разврат...
← →
MgFox (2004-12-30 10:32) [3]Базовый класс не имеет такого интерфеса и при попыткке сделать
IMyIntf(TBaseClass(ptr)).callMe;
Delphi говорит что такое оно компилять не станет ибо типы IMyIntf и TBaseClass не совместимы.
PS: Сорри в исходном сообщении обшибочка
класс на самом деле делается так:TMyClass=class(TBaseClass,IMyIntf) ...
← →
MgFox (2004-12-30 10:33) [4]to Palladin
IMyIntf(ptr^).callMe;
не спасает, результат тот-же - Exception
← →
Palladin © (2004-12-30 10:36) [5]
> Базовый класс не имеет такого интерфеса и при попыткке сделать
> IMyIntf(TBaseClass(ptr)).callMe;
А это вообще порнуха. Почему бы тебе не определить в таком случае этот интерфейс для базового класса? Если все же получение интерфеса проводится точно для именно правильного наследника то есть оператор AS и вообще приведение типов. Это первое. Второе
> А экземпляр этого класса хранится не в обычной переменной
> я в переменной типа Pointer валяется на него ссылка.
Идентификатор экземпляра класса сам по себе уже ссылка. Для чего тебе ссылка на ссылку? И если уж используешь это то и работай тогда с ней как с ptr^
← →
Sandman25 © (2004-12-30 10:36) [6]Повторяю.
(TMyClass(prt) as IMyIntf).Callme
← →
Digitman © (2004-12-30 10:38) [7]
> экземпляр этого класса хранится не в обычной переменной
> я в переменной типа Pointer валяется на него ссылка.
зачем хранить в переменной указатель на объект ? смысл какой ? ты же все равно будешь обращаться к этому объекту через его интерфейс ..
храни там, в переменной, прямо интерфейсную ссылку !
если заранее не знаешь, какой интерфейс там будет храниться, объяви как IUnknown, а в нужный момент приводи к нужному интерф.типу ... примерно так :
var
ptr: IUnknown;
..
ptr := TMyClass.Create;
..
IMyIntf(ptr).Callme
← →
MgFox (2004-12-30 10:41) [8]to Sandman25
> Повторяю.
> (TMyClass(prt) as IMyIntf).Callme
так нельзя сделать т.к.
наследников базового класса у меня дцать и конкретный тип объекта, с которым осуществляется взаимодействие, неизвестен.
Для этого и был нарисован интерфейс дабы не париться с типом объекта.
← →
MgFox (2004-12-30 10:43) [9]to Digitman
я не могу его хранить как-то иначе чем через Pointer т.к. хранится оно не у меня, а в компоненте, в которой для хранения объектов есть аттрибутData:Pointer;
← →
MgFox (2004-12-30 10:48) [10]to Palladin
//Идентификатор экземпляра класса сам по себе уже ссылка. Для чего тебе ссылка на ссылку? И если уж используешь это то и работай тогда с ней как с ptr^
Если я присваиваю указателю значение так:ptr := TMyClass.Create();
как мне с ним работать ?
← →
Sandman25 © (2004-12-30 10:50) [11][8] MgFox (30.12.04 10:41)
Значит нужно завести промежуточный класс с интерфейсом, или добавить поддержку интерфейса прямо в baseclass.
← →
Sandman25 © (2004-12-30 10:51) [12]А вообще если есть общий предок, то интерфейсы не нужны. Достаточно описать виртуальный метод в предке.
← →
Digitman © (2004-12-30 11:32) [13]
> я не могу
что это вдруг не можешь ? еще как можешь !
свойство типа Pointer ничем не отличается от переменной типа пойнтер , все практически так же будет выглядеть и в случае со св-вом ..
но я бы посоветовал наследовать свой TMyClass не от TObject, а от TInterfacedObject - там уже реализован подсчет ссылок и автоуничтожение объекта при сч-ке ссылок = 0
SomeObject.Data := Pointer(TMyClass.Create as IMyIntf); //происходит инкремент сч-ка ссылок
..
//вызываем интерфейсный метод
IMyIntf(SomeObject.Data).Callme; //инкремента сч-ка ссылок не происходит !
..
//интерфейс более не нужен - декрементируем сч-к ссылок
IMyIntf(SomeObject.Data)._Release;
← →
Erik1 © (2004-12-30 11:50) [14]Непонятно что тебе точно нужно, но для общего развития: можно запросить интерфейс у объекта.
var
IPreview: IPreviewLayer;
begin
if Assigned(SomeObject.Data) and TObject(SomeObject.Data).GetInterface(IPreviewLayer,
IPreview) then
IPreview.Callme;
← →
Cobalt © (2004-12-30 12:59) [15]Digitman © (30.12.04 11:32) [13]
//интерфейс более не нужен - декрементируем сч-к ссылок
IMyIntf(SomeObject.Data)._Release;
Немного здоровой критики:IMyIntf(SomeObject.Data):=nil;
?
← →
kull (2004-12-30 15:32) [16]Digitman все правильно написал, помоему этого достаточно.
Типа так и надо:
P: Pointer;
...
IUnknown(P) := MyInterface;
...
IUnknown(P) := nil;
...
Только на всякий случай надо в начале P := nil сделать, если не было раньше инициализации P, а то на присваивании
IUnknown(P) := MyInterface;
Может Exception случиться. Я уже сталкивался с этим.))
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.01.16;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.057 c