Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.59 MB
Время: 0.03 c
14-13778
Химик
2002-07-10 10:46
2002.08.05
Задачка на засыпку


6-13738
Aliev Adil
2002-05-21 14:05
2002.08.05
Perl


7-13828
Losyara
2002-05-18 22:46
2002.08.05
Ошибка Large Fonts


1-13589
kingdom
2002-07-24 14:18
2002.08.05
Как перебрать элементы нулевого уровня у TreeView


1-13614
Freeze
2002-07-25 07:08
2002.08.05
Масштаб картинки TImage





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский