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

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

Интерфейсы [D6, Win2k]


Vlad2 ©   (2002-07-23 11:33:00) 

Проясните, пожалуйста, ситуацию:
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.


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

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


vuk   (2002-07-23 15:37:00) [2]

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

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


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

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


vuk   (2002-07-23 13:39:00) [4]

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


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

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


Digitman   (2002-07-23 12:20:00) [6]

>Skier

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


Skier   (2002-07-23 12:13:00) [7]

>Vlad2
В догонку :

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

TInterfacedObject._AddRef
и TInterfacedObject._Release


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

>Vlad2
Bingo !


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

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


Skier   (2002-07-23 12:08:00) [10]

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


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


Digitman   (2002-07-23 12:06:00) [11]

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


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

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

>Skier

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


Skier   (2002-07-23 11:46:00) [13]

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


Digitman   (2002-07-23 11:43:00) [14]

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


Skier   (2002-07-23 11:37:00) [15]

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

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

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


Наверх

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