Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Не уничтожаются объекты класса (число прочтений - 4186 )
mash
1c++ donor
Отсутствует


1C++ v. 3.0.1.23

Сообщений: 148
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Не уничтожаются объекты класса
14. Июля 2009 :: 11:04
Печать  
Столкнулся с непонятной вещью, которую не могу объяснить.  И через это прошу помощи зала.

Есть некий класс - назовем его "[i]Фабрика[/i]". Он создает в процедуре, экземпляры неких третьих классов, назовем их "[i]Класс1[/i]" и "[i]Класс2[/i]", инициализирует их своим контекстом, но [u]нигде у себя ссылок на созданные объекты не сохраняет[/u], а сразу передает клиенту.  Вот его код:
[code]Функция Создать(_имя) Экспорт
     _класс = СоздатьОбъект(_имя);
     _класс.УстановитьКонтекстФабрика(Контекст);
     Возврат _класс;
КонецФункции
// ***
Процедура Конструктор()
     Сообщить("Конструктор ""фабрика"" ");
КонецПроцедуры
// ***
Процедура Деструктор()
     Сообщить("Деструктор ""фабрика"" ");
КонецПроцедуры[/code]


Классы "[i]класс1[/i]" и "[i]класс2[/i]", в свою очередь хранят у себя контекст класса "[i]Фабрика[/i]", но сами в "[i]Фабрике[/i]" не хранятся.  Вот их код:
[code]Перем _контекстФабрика;
перем _имяКласса;

Процедура Конструктор()
     _имяКласса = Строка(вирт());
     Сообщить("Конструктор "+_имяКласса);
КонецПроцедуры
// ***
Процедура УстановитьКонтекстФабрика(_конт)  Экспорт
     _контекстФабрика = _конт;
КонецПроцедуры
//***
Процедура Деструктор()
     Сообщить("Деструктор "+_имяКласса);
КонецПроцедуры
[/code]


И есть такая простенькая обработочка :

[code]      _оФабрика = СоздатьОбъект("Фабрика");
     Сообщить("Создаем класс 1");
     _оКласс1 = _оФабрика.Создать("Класс1");
     Сообщить("Создаем класс 2");
     _оКласс2 = _оФабрика.Создать("Класс2");
     Сообщить("Уничтожаем класс 1");
     _оКласс1 = 0;
     Сообщить("Уничтожаем класс 2");
     _оКласс2 = 0;
     Сообщить("Уничтожаем фабрику");
     _оФабрика = 0;[/code]

так вот, судя по логам. Уничтожается только объект класса "Класс1", а объект класса "Класс2" и "Фабрика" не уничтожаются (даже после закрытия окна формы). Вопрос - почему ? Единственное разумное объяснение - циклические ссылки, но мне их в этом примере не видно :(

выгрузка в аттаче.

ЗЫ Первоначально это все [i]не работало[/i] через "Делегат", но упростив пример, я понял, что не в делегате дело.
  

test_delegat.zip ( 9 KB | Загрузки )

Поспешность наносит ущерб
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #1 - 14. Июля 2009 :: 12:52
Печать  
а хочеш еще сильнее удивиться? Улыбка
добавь в Фабрику метод:
Код
Выбрать все
Функция Почистить_RetValue_КоторыйЕсть_Статический_CValue() Экспорт
	Возврат "";
КонецФункции
//т.е. своего рода избавление от неявной ссылки
 


а в тесте напиши так:
Код
Выбрать все
Процедура Выполнить()
 	_оФабрика = СоздатьОбъект("Фабрика");
	Сообщить("Создаем класс 1");
	_оКласс1 = _оФабрика.Создать("Класс1");
	Сообщить("Создаем класс 2");
	_оКласс2 = _оФабрика.Создать("Класс2");
	_оФабрика.Почистить_RetValue_КоторыйЕсть_Статический_CValue();
	Сообщить("Уничтожаем класс 1");
	_оКласс1 = 0;
	Сообщить("Уничтожаем класс 2");
	_оКласс2 = 0;
	Сообщить("Уничтожаем фабрику");
	_оФабрика = 0;
КонецПроцедуры 

« Последняя редакция: 15. Июля 2009 :: 05:50 - trad »  

1&&2&&3
Наверх
 
IP записан
 
mash
1c++ donor
Отсутствует


1C++ v. 3.0.1.23

Сообщений: 148
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #2 - 14. Июля 2009 :: 13:21
Печать  
О ! Шаманский бубен  Улыбка

С этим заклинанием работает Улыбка И шо это было ?  Подмигивание
  

Поспешность наносит ущерб
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #3 - 14. Июля 2009 :: 13:26
Печать  
mash писал(а) 14. Июля 2009 :: 13:21:
И шо это было ?  Подмигивание
имхо, подстава от 1с.
Как полечить не представляю.
Можно только подогнать логику: например возвращать экземпляр через параметр.
  

1&&2&&3
Наверх
 
IP записан
 
mash
1c++ donor
Отсутствует


1C++ v. 3.0.1.23

Сообщений: 148
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #4 - 14. Июля 2009 :: 13:29
Печать  
Т.е. всегда есть неявная ссылка на последнее возвращенное значение в модуле ? так что ли ?

upd почитал про подобное вот здесь http://itland.ru/forum//index.php?showtopic=820&hl=%EF%EE%E6%E8%F0%E0%F2%E5%EB%F...

Там, правда, говорится про функцию, но, я так полагаю, проблема с последним возвращенным значением применима к объекту в целом
  

Поспешность наносит ущерб
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #5 - 14. Июля 2009 :: 13:40
Печать  
mash писал(а) 14. Июля 2009 :: 13:29:
Т.е. всегда есть неявная ссылка на последнее возвращенное значение в модуле ? так что ли ?
да
Изменено:
уточню: в модуле копа
  

1&&2&&3
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #6 - 14. Июля 2009 :: 13:45
Печать  
mash писал(а) 14. Июля 2009 :: 13:29:
upd почитал про подобное вот здесь http://itland.ru/forum//index.php?showtopic=820&hl=%EF%EE%E6%E8%F0%E0%F2%E5%EB%F...

Там, правда, говорится про функцию, но, я так полагаю, проблема с последним возвращенным значением применима к объекту в целом

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

1&&2&&3
Наверх
 
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #7 - 15. Июля 2009 :: 04:26
Печать  
[quote author=mash link=1247569443/0#0 date=1247569443]
Классы "[i]класс1[/i]" и "[i]класс2[/i]", в свою очередь хранят у себя контекст класса "[i]Фабрика[/i]"[/quote]
Это академический пример или он имеет какую-то практическую ценность?
  
Наверх
www  
IP записан
 
mash
1c++ donor
Отсутствует


1C++ v. 3.0.1.23

Сообщений: 148
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #8 - 15. Июля 2009 :: 06:50
Печать  
Это упрощенный практический пример.  В оригинале там используется  Делегат, но суть та же.

Классы Класс1, Класс2 - алгоритмы некоего мультиалгоритмического документа (типа ЗакрытиеМесяца), класс Фабрика - коллекция этих алгоритмов. Клиент (модуль документа) - получает (с помощью класса Фабрика) экземпляры нужных ему классов алгоритмов, которые при своей работе отправляют в объект класса Фабрика сообщения трассировки (с помощью вызова через Делегат метода класса Фабрика), где они и собираются с помощью объекта агрегированного класса Трассировка.

При необходимости (аргументе метода Провести()) клиент делает _оФабрика.ПоказатьТрассировку() и выскакивает окно подобное трассировкам из стандартных конфигураций.

Сейчас я переделал вызовы с
Код
Выбрать все
_оКОП = ПолучитьАлгоритм(_имяАлгоритма); 


на
Код
Выбрать все
_флПолученУспешно = ПолучитьАлгоритм(_имяАлгоритма, _оКОП); 


и утечек больше нет Улыбка Заодно и обработку исключительных ситуаций (когда экземпляр класса алгоритма создать невозможно) без выброса из программы настроил Улыбка
  

Поспешность наносит ущерб
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #9 - 15. Июля 2009 :: 07:06
Печать  
mash писал(а) 15. Июля 2009 :: 06:50:
которые при своей работе отправляют в объект класса Фабрика сообщения трассировки (с помощью вызова через Делегат метода класса Фабрика), где они и собираются с помощью объекта агрегированного класса Трассировка.

А почему не передавать в классы сразу объект класса Трассировка?
  
Наверх
www  
IP записан
 
mash
1c++ donor
Отсутствует


1C++ v. 3.0.1.23

Сообщений: 148
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #10 - 15. Июля 2009 :: 07:38
Печать  
В принципе, можно, конечно, и так.

Но тут я преследовал две цели:

  • Создание простого, универсального механизма взаимодействия объекта классов-коллекций с объектами классов-членов через делегата.
  • Максимальное сокрытие механизмов трассировки (и самого объекта оТрассировка) в соответствии с принципами инкапсуляции. Кроме того - все работы по обработке сообщений (присвоение тегов, уровней итп) удобнее вести в одном месте, чтобы проще было потом менять, если что.

  

Поспешность наносит ущерб
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


I wanted to cry, but the
tears wouldn't come

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Не уничтожаются объекты класса
Ответ #11 - 15. Июля 2009 :: 08:08
Печать  
Ага, примерно понял.
  
Наверх
www  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать