Форум: "Основная";
Текущий архив: 2002.08.05;
Скачать: [xml.tar.bz2];
ВнизИнтерфейсы Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.004 c