Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Фабрика некоректно создает производный класс (число прочтений - 4356 )
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Фабрика некоректно создает производный класс
10. Марта 2008 :: 11:47
Печать  
Суть проблемы

имеем три класса
Код
Выбрать все
class Базовый = класс_Базовый@MD{}
class ТестКлассНеПроизводный = класс_КлассНеПроизводный@MD{}
class ТестКлассПроизводный = класс_КлассПроизводный@MD : Базовый {}
 



в каждом тестовом классе реализуем следующий функционал
Код
Выбрать все
Перем _ВыполняемыйМодуль;

Процедура СоздатьЭкземпляр()
	Сообщить("Создан экземпляр объекта через конструктор СоздатьЭкземпляр");

КонецПроцедуры	// СоздатьЭкземпляр

Процедура Конструктор()
	_ВыполняемыйМодуль = СоздатьОбъект("ВыполняемыйМодуль");
	_ВыполняемыйМодуль.СформироватьОшибку("в текущем режиме вызова Конструктора не должно происходить");


КонецПроцедуры	// Конструктор

 



делаем вызов следующего характера
Код
Выбрать все
_Фабрика = СоздатьОбъект("ФабрикаОбъектов");
	Попытка
		//тест раз
		обОбычныйКласс = _Фабрика.Новый("ТестКлассНеПроизводный","СоздатьЭкземпляр");

		//тест два
		обПроизводныйКласс = _Фабрика.Новый("ТестКлассПроизводный","СоздатьЭкземпляр");
	Исключение
		РезультатТестов = 0;
		Сообщить(ОписаниеОшибки(),"!!!");
	КонецПопытки;
 



и имеем следующее

Код
Выбрать все
ТестКлассПроизводный::Конструктор() : в текущем режиме вызова Конструктора не должно происходить
_ВыполняемыйМодуль.СформироватьОшибку("в текущем режиме вызова Конструктора не должно происходить");
 



Вопрос: получается если класс является наследником от Базового вызова конструктора указанного в параметр Фабрики не произойдет?

испробовано на стабильном релизе 2.5.0.5
и на ночных сборках от 7 февраля 2008 года и от 28 февраля 2008 года

Это нормально или я туплю  Нерешительный




  

TestOfFabricAndExtenedClass.zip ( 10 KB | Загрузки )

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #1 - 10. Марта 2008 :: 13:54
Печать  
ситуация такова (по крайней мере на исходниках стабильного релиза)

если пользовательский класс является наследником то при вызове CComponentClass::InvokeConstructor()
отрабатывает условие if (-1 != defFnNames->nPosConstructor && !bFlagCreateWithoutConstructor)

собственно в таком случае bFlagCreateWithoutConstructor = 0 и nPosConstructor = 1

проблема в принципе решается "убиранием" процедуры с названием Конструктор из модуля класса - но как мне тогда запретить создавать экземпляр методом СоздатьОбъект()  Нерешительный

Продолжаю исследование - ведь если наследником не является - то всё нормально  Круглые глаза
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #2 - 10. Марта 2008 :: 14:23
Печать  
На конец дня (а он у меня сегодня рабочий) пока выкрутился так

неявное назначение базового класса (хотя вроде говорили что это плохо)

Код
Выбрать все
//#preprocessor off
Перем База;
Перем _ВыполняемыйМодуль;

Функция Этот(Конт) Возврат Конт; КонецФункции
Функция Сам() Возврат Этот(Контекст) КонецФункции

Процедура СоздатьЭкземпляр()
	База = СоздатьОбъект("Базовый");
	Сам().ЗаменитьЭксзБазовогоКласса("Базовый", База);
	Сообщить("Создан экземпляр объекта через конструктор СоздатьЭкземпляр");
КонецПроцедуры	// СоздатьЭкземпляр

Процедура Конструктор()
	_ВыполняемыйМодуль = СоздатьОбъект("ВыполняемыйМодуль");
	_ВыполняемыйМодуль.СформироватьОшибку("в текущем режиме вызова Конструктора не должно происходить");
КонецПроцедуры	// Конструктор
 



сооответственно из defcls.prm  необходимо убрать явное указание класса от кого наследовать  Язык
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #3 - 11. Марта 2008 :: 16:30
Печать  
За исследование кода С++ спасибо.
Но где же самое главное - баг в багзилле Печаль ?
Без этого баг править не буду Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
fez
Forum Administrator
1c++ power user
Отсутствует


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

Сообщений: 2712
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #4 - 11. Марта 2008 :: 16:32
Печать  
artbear писал(а) 11. Марта 2008 :: 16:30:
За исследование кода С++ спасибо.
Но где же самое главное - баг в багзилле Печаль ?
Без этого баг править не буду Улыбка

http://www.1cpp.ru/bugs/show_bug.cgi?id=3621
Еще вчера создан.
  
Наверх
www  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #5 - 11. Марта 2008 :: 16:36
Печать  
lustin писал(а) 10. Марта 2008 :: 14:23:
неявное назначение базового класса (хотя вроде говорили что это плохо)

Код
Выбрать все
	База = СоздатьОбъект("Базовый");
	Сам().ЗаменитьЭксзБазовогоКласса("Базовый", База);
 



соответственно из defcls.prm  необходимо убрать явное указание класса от кого наследовать  Язык

Т.е. ты хочешь сказать, что у нас в ООП есть такая лазейка/черный ход Печаль Печаль ??? Если в описании класса не указано, что он является чьим-то наследником, то его можно унаследовать от любого класса ????
Да, я об этом даже и не думал, соответственно, и теста нету Улыбка

Это или явный баг или хорошая фича Улыбка

Прошу оба случая описать в багзилле.
Постараюсь на этой или следующей неделе решить.
ЗЫ без багзиллы решать не буду Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #6 - 11. Марта 2008 :: 16:36
Печать  
fez писал(а) 11. Марта 2008 :: 16:32:
artbear писал(а) 11. Марта 2008 :: 16:30:
За исследование кода С++ спасибо.
Но где же самое главное - баг в багзилле Печаль ?
Без этого баг править не буду Улыбка

http://www.1cpp.ru/bugs/show_bug.cgi?id=3621
Еще вчера создан.

Упс, только вышел из оффлайна Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #7 - 13. Марта 2008 :: 17:13
Печать  
artbear писал(а) 11. Марта 2008 :: 16:36:
Это или явный баг или хорошая фича Улыбка


не знаю как считать - но есть один момент который известен точно при таком вызове

при стандартном описании через defcls.prm процедуры Конструкторы вызываются рекурсивно и соответственно первым вызывается конструктор базового класса

в если через вот такой хитрый способ с назначением базового класса - первым отработает конструктор производного класса Улыбка
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #8 - 16. Марта 2008 :: 10:08
Печать  
lustin писал(а) 10. Марта 2008 :: 11:47:
Вопрос: получается если класс является наследником от Базового вызова конструктора указанного в параметр Фабрики не произойдет?

На самом деле сейчас при этом идет такая схема вызова -
1. обычный Конструктор базового класса
2. далее идет обычный Конструктор класса-наследника
3. и только теперь идет вызов произвольного конструктора.
Схема, конечно, неверна Печаль
И понятно, почему у тебя не работает вызов - у тебя облом на шаге 2. Печаль
Разбираюсь

  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #9 - 16. Марта 2008 :: 11:37
Печать  
Исходный баг исправлен.
Будет в ночной сборке 2.5 от 17.03.08
Прошу автора проверить, подтвердить и закрыть баг в багзилле.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #10 - 16. Марта 2008 :: 11:47
Печать  
artbear писал(а) 16. Марта 2008 :: 11:37:
Исходный баг исправлен.
Будет в ночной сборке 2.5 от 17.03.08
Прошу автора проверить, подтвердить и закрыть баг в багзилле.


будет сделано

за сегодня также опишу схему произвольного наследования  Улыбка
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Фабрика некоректно создает производный класс
Ответ #11 - 16. Марта 2008 :: 12:50
Печать  
lustin писал(а) 10. Марта 2008 :: 14:23:
неявное назначение базового класса (хотя вроде говорили что это плохо)

Код
Выбрать все
Перем База;

Процедура СоздатьЭкземпляр()
	База = СоздатьОбъект("Базовый");
	Сам().ЗаменитьЭксзБазовогоКласса("Базовый", База);
КонецПроцедуры	// СоздатьЭкземпляр 



сооответственно из defcls.prm  необходимо убрать явное указание класса от кого наследовать  Язык

Оказывается, все у нас с неявным назначением нормально, т.е. оно запрещено. А я просто сразу не разобрался.
Дело в том, что твой код Сам().ЗаменитьЭксзБазовогоКласса("Базовый", База); попросту не работает Улыбка
например, напиши
Код
Выбрать все
фРез = Сам().ЗаменитьЭксзБазовогоКласса("Базовый", База);
Сообщить("фРез = <"+фРез+">");
лБаза = Сам().ПолучитьБазовыйОбъект("Базовый");
Сообщить("лБаза = <"+ТипЗначенияСтр(лБаза)+">");
 


и сам все увидишь Улыбка
Соответственно, используемая тобой схема к наследованию имеет слабое отношение Улыбка, скорее это что-то типа паттернов фасад, оболочка и т.д.

ЗЫ кстати, вместо ЗаменитьЭксзБазовогоКласса намного юзабельнее ЗаменитьБазовыйОбъект Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать