[РЕШЕНО] Интерфейс и явный вызов деструктора

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

[РЕШЕНО] Интерфейс и явный вызов деструктора

Сообщение Brainenjii » 25.07.2011 11:05:10

Никогда не работал с интерфейсами (старался обходиться классами и наследованием). Вот решил применить интерфейс (не относящийся к проблеме код убран):
Код: Выделить всё
Var
  aObject: BObjectClass;
  aManager: BManagerClass;
  aForm: BFormStatusClass;
Begin
  aObject := nil;
  aManager := nil;
  With CurrentThread Do
    Begin
      If HasParam('Activity') Then
        Begin
          aObject := ActivityManager.ChangeActivity(ByInteger('Activity'));
          aManager :=ActivityManager;
        End;
      (aObject As IStatus).SetStatus(bsWork);
      aObject.Burn; // <- Ошибка
    End;

Если мы уберем строку (aObject As IStatus).SetStatus(bsWork); - исключение не поднимется. Если мы опишем:
Код: Выделить всё
Var
  aObject: BObjectClass;
  aManager: BManagerClass;
  aForm: BFormStatusClass;
Begin
  aObject := nil;
  aManager := nil;
  With CurrentThread Do
    Begin
      If HasParam('Activity') Then
        Begin
          aObject := ActivityManager.ChangeActivity(ByInteger('Activity'));
          aManager :=ActivityManager;
        End;
      BActivityClass(aObject).SetStatus(bsWork);
      aObject.Burn; // <- теперь ошибки нет
    End;

то опять же, код выполнится замечательно. Что происходит с aObject после (aObject As IStatus).SetStatus(bsWork);?
Последний раз редактировалось Brainenjii 25.07.2011 14:57:30, всего редактировалось 2 раз(а).
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Интерфейс и ошибка 204 (Invalid Pointer Operation)

Сообщение hinst » 25.07.2011 11:14:50

а может быть, ошибка на предыдущей строке? Отладчик же иногда показывает на следующую строчку после той, на которой произошло исключение
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Интерфейс и ошибка 204 (Invalid Pointer Operation)

Сообщение Brainenjii » 25.07.2011 11:19:24

Боюсь, нет - отладчик останавливается именно в деструторе Burn, попробовал вставить отладочную строку после вызова интерфейсной функции - она отработала. Но на Burn все-равно ловлю исключение...

Добавлено спустя 14 минут 10 секунд:
тут нашёл в интернетах -
delphimaster.ru писал(а):Для потомков TInterfacedObject нельзя явно вызывать деструктор. Это происходит автоматически при обнулении кол-ва ссылок.

Если это так, то как быть?
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Интерфейс и ошибка 204 (Invalid Pointer Operation)

Сообщение hinst » 25.07.2011 11:44:12

Щито? Burn - это какой такой деструктор. Free надо юзать.
Во-вторых, как быть с деструктором: напиши
Код: Выделить всё
aObject:=nil

Подсчёт ссылок же. Когда объект (который интерфейс) увидит, что на него нет больше ссылок, он освободит свою душу
А можешь и не писать, ведь при выходе из процедуры он освободится и так
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Интерфейс и ошибка 204 (Invalid Pointer Operation)

Сообщение Brainenjii » 25.07.2011 11:58:23

Угу... Т.е. если я использую интерфейсы, то уничтожать я не должен, а должен обнулять... Сейчас попробовал - всё прошло, и даже в Burn зашло, когда все ссылки кончились... Но тогда мне придётся перелопатить уйму кода - убрать все явные деструкторы...
Есть какой-нибудь способы обмануть счетчик ссылок? A то и интерфейсы хочется, и деструторы явно вызывать ^_^
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Интерфейс и явный вызов деструктора

Сообщение hinst » 25.07.2011 12:27:50

когда ты делаешь свой класс реализующим интерфейс, то ты можешь перекрыть методы _addref и _release, или как там они называются. Они будут вызываться каждый раз добавляется новая ссылка на объект или пропадает существующая ссылка. Вот их и перекрываешь. По дефолту там стоит, насколько я знаю, но это можно уточнить
Код: Выделить всё
if refcount = 0 then Free;

Вот ссылочка на статью http://www.freepascal.org/docs-html/rtl ... known.html

И, в общем, перекрыв руками эти два метода, ты можешь заставать вести себя объект в зависимости от увеличения и уменьшения количества ссылок на него так, как тебе хочется
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Интерфейс и явный вызов деструктора

Сообщение Brainenjii » 25.07.2011 12:43:33

Нашёл это, спасибо. Но даже убрав автоматическую очистку при frefcount = 0 - все-равно вызывается Access Violation, если объект уже уничтожен (по всей видимости при входе в _Release: Longint :-(

Добавлено спустя 12 минут 15 секунд:
Можно ли избавиться от механизма подсчета ссылок вообще?
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Интерфейс и явный вызов деструктора

Сообщение hinst » 25.07.2011 12:57:17

1. А override написал?
2. А проверку self <> nil в своём методе написал?
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Интерфейс и явный вызов деструктора

Сообщение Odyssey » 25.07.2011 14:32:51

Brainenjii писал(а):Можно ли избавиться от механизма подсчета ссылок вообще?

Если я правильно понимаю, то:
* можно переключить вид интерфейсов с COM на CORBA с помощью {$interfaces CORBA}, у CORBA-интерфейсов автоматического подсчёта ссылок нет (пруф);
* при использовании CORBA-интерфейсов не нужно наследоваться от TInterfacedObject (пруф).
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: Интерфейс и явный вызов деструктора

Сообщение Brainenjii » 25.07.2011 14:57:14

Круто! Спасибо, наверняка это решит проблему (сейчас уже реализовал как привычно - через базовый класс).
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19

Рейтинг@Mail.ru