Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.08.05;
Скачать: CL | DM;

Вниз

Интерфейсы   Найти похожие ветки 

 
Vlad2   (2002-07-23 11:33) [0]

Проясните, пожалуйста, ситуацию:
1. Существуют два объекта (o1, o2), - наследники TForm;
2. Оба они реализуют интерфейс IanyInterface;
3. В тексте модуля создается интерфейсная ссылка ai: IanyInterface;
ai := o1.Create или ai := o2.Create
4. При выполнении ai := nil; деструкторы объектов o1 или o2
не вызываются. Поэтому, перед созданием интерфейсной ссылки
приходится определять тип созданного объекта и вызывать
o1.Free или o2.Free
Непонятно, - почему не вызываются деструкторы при ai := nil ?
С уважением, Vlad2.


 
Skier ©   (2002-07-23 11:37) [1]

>Vlad2
Потому что не считаются ссылки.

Загляни в методы класса-предка

function _AddRef: Integer; stdcall; и
function _Release: Integer; stdcall;


 
Digitman ©   (2002-07-23 11:43) [2]

ai := o1.Create as IAnyInterface;
ai := nil;


 
Skier ©   (2002-07-23 11:46) [3]

>Digitman
as IAnyInterface а это зачем ?


 
Digitman ©   (2002-07-23 12:03) [4]

>Skier
Да , в общем-то, необязательно, согласен ...
Но для общего случая, когда объект может реализовать более одного интерфейса, это гораздо наглядней, согласись

>Skier

Деструктор объекта, в общем случае, следует вызывать в реализации интерфейсного метода IUnknown._Release (при достижении RefCount = 0, сч-к ссылок же инкрементируется в теле IUnknown._AddRef). То, что тебе удалось скомпилировать код модуля, говорит о том, что какую-то реализацию этого метода ты все же выполнил. Но вот отсутствие автовызова деструктора, скорее всего, говорит именно о том, что нигде в обязательной реализации методов интерфейса IUnknown подобный код не присутствует у тебя


 
Digitman ©   (2002-07-23 12:06) [5]

<Skyer>, извини, последняя реплика не по адресу - она для <Vlad2>


 
Skier ©   (2002-07-23 12:08) [6]

>Digitman
У него "подсчёт ссылок" (хотя там ничего не считается)
уходит, видимо, сюда :


function TComponent._AddRef: Integer; stdcall;
function TComponent._Release: Integer; stdcall;


 
Vlad2   (2002-07-23 12:10) [7]

Что - то проясняется. Спасибо. Но
to Skier: я должен реализовать методы
_AddRef и
_Release
в своих классах o1 и o2 ?


 
Skier ©   (2002-07-23 12:11) [8]

>Vlad2
Bingo !


 
Skier ©   (2002-07-23 12:13) [9]

>Vlad2
В догонку :

Код можно взять из

TInterfacedObject._AddRef
и TInterfacedObject._Release


 
Vlad2   (2002-07-23 12:20) [10]

Ребята ! Всем спасибо. Очень-очень и все все все.


 
Digitman ©   (2002-07-23 12:20) [11]

>Skier

Точно !
Я и забыл совсем, что TComponent их реализует) Поэтому и компилятор "молчит"


 
vuk ©   (2002-07-23 13:39) [12]

Если Вы реализуете интерфейсы в наследниках TComponent, то нужно быть осторожным с подсчетом ссылок, т.к. в случае с компонентами временем жизни объекта обычно управляет не он сам, а его владелец, поэтому возможны неприятности...


 
Vlad2   (2002-07-23 15:03) [13]

>vuk
Если я правильно понял, может возникнуть ситуация, когда владелец выполнил Destroy объекта, а реализованный в нем метод
_Release не выполнился ?


 
vuk ©   (2002-07-23 15:37) [14]

Нет не это имелось в виду. Предположим, у Вас есть компонент реализующий интерфейс (с учетом подсчета ссылок) и Вы создаете компонент.
При этом возможны следующие ситуации:
1. Вы запрашиваете интерфейс, работаете с ним, а при выходе из процедуры, где это все делается, Ваш компонент будет автоматически уничтожен (что, скорее всего, Вам не нужно), поскольку счетчик ссылок будет равен 0.

2. Вы где-то запрашиваете у этого компонента интерфейс и сохраняете его в переменной. После чего в каком-то другом месте пытаетесь удалить владельца компонента. Естественно, получите исключение, поскольку имеются ссылки на интерфейс...


 
Vlad2   (2002-07-24 06:46) [15]

>vuk
Прошу извинить за паузу.
Мне кажется, все работает так: интерфейсные ссылки вначале выполняют _Release, а затем Destroy (при необходимости); а объектные ссылки сразу выполняют Destroy (например, при удалении владельца). Т.е. объект может быть удален разными способами, и в каждом нужно соблюсти корректность. А если добавить в деструктор владельца вызов _Release ?



Страницы: 1 вся ветка

Текущий архив: 2002.08.05;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.018 c
14-13792
Человек в белом халате
2002-07-10 15:23
2002.08.05
Чувак13


1-13683
BKV
2002-07-23 21:32
2002.08.05
Как узнать текущее координаты Курсора мыши?


1-13632
dimanew
2002-07-23 06:49
2002.08.05
Как в DBGride сделать подсветку одной строки например на 2 сек?


1-13704
ask
2002-07-24 11:32
2002.08.05
string -> char


14-13786
Вася______
2002-07-10 13:14
2002.08.05
База данных