AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.07.2008, 12:22   #1  
NNB is offline
NNB
Участник
 
103 / 12 (1) ++
Регистрация: 31.08.2006
new() и init()
Добрый день
Стало любопытно умеет init() класса того, что не умеет new()
Старый 08.07.2008, 12:27   #2  
Sada is offline
Sada
Программатор
Аватар для Sada
 
1,450 / 153 (8) ++++++
Регистрация: 29.03.2005
Адрес: Толи Барнаул, толи Москва
Краткость конечно сестра таланта, но не на столько же.
Старый 08.07.2008, 12:32   #3  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
Цитата:
Стало любопытно умеет init() класса того, что не умеет new()
Не совсем понятный вопрос.
new() - конструктор, присутствует в любом классе.
init() - просто метод, присутствует не во всех классах.
Технически - это обычные методы и могут содержать любой код. Далее - всё зависит от логики потроения класса. В кернеловских классах (в частности на формах) конструктор лучше не трогать - сразу взлет.
Старый 08.07.2008, 12:33   #4  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Теперь хоть понятно, откуда берутся такие требования к программистам. Давайте стараться писать по-русски.
Цитата:
Сообщение от Serge Kotov Посмотреть сообщение
Русский на уровне ЕГЭ
Старый 08.07.2008, 22:25   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от NNB Посмотреть сообщение
Добрый день
Стало любопытно умеет init() класса того, что не умеет new()
init() можно запустить повторно. Предполагается что будет выполнена переинициализация. уже созданных объектов.
new() создает объекты. Как правило, на уже существующем объекте повторно его вызывать нельзя.
__________________
полезное на axForum, github, vk, coub.
Старый 09.07.2008, 00:18   #6  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от NNB Посмотреть сообщение
Стало любопытно умеет init() класса того, что не умеет new()
Не сочтите за снобизм, но напомнило Joel on Software, Назад, к основам:
Цитата:
Я придерживаюсь мнения, что студенты, начинающие изучать программирование, должны начинать с начала, использовать C и подниматься вверх от процессора. Мне противно, как часто программа обучения строится на посылке, что Java представляет собой хороший язык для того, чтобы начинать программировать, потому что это так "просто" и не нужно отвлекаться на эти скучные детали про строки и выделение памяти, и сразу можно изучить кульные ООП-штучки которые помогут сделать ваши большие программы так восхитительно модульными.
Так вот, основы применительно к данной теме состоят в том, что при динамическом создании объекта надо, видите ли, выделять для него память. Именно этим и занимается, кроме прочего, метод new() в Аксапте, даже если вы его не перекрываете и ничего явно не инициализируете. При вызове этого метода, кроме прочего, происходит самое что ни на есть физическое выделение памяти для объекта (экземпляра класса, как угодно); другое дело, что Аксапта скрывает такие подробности, потому что обеспечивает автоматическое управление памятью, и начинает, видимо, казаться, что создать объект и инициализировать его - это одно и то же. Ан-нет... И еще обратите внимание, что метод new() вызывается для класса (т.е. типа данных), в то время как init() вызывается для объекта (экземпляра класса). Наглядно - даже, наврено, слишком наглядно - это все можно наблюдать в отладчике: если следить за переменной, которой присваивается ссылка на создаваемый объект, то пока вы не выйдите успешно из метода new(), ссылка эта показывается пустой, а как только объект создан, она уже показывается как ссылающаяся на экземпляр определенного класса со всеми его внутренними переменными.
В общем-то, все ключевые слова тут уже упоминали; если вы прежде изучали ООП, то разница между конструктором класса и методом класса должна вам все объяснить.
Старый 09.07.2008, 12:14   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
gl00mie

Как мне кажется, происходит путаница понятий

В системе Axapta создание объекта - это команда

X++:
myVar = new MyObject()
Кажется, что команда new вызывает непосредственно метод new() объекта. Однако если бы это было действительно так, то внутри метода new() объекта невозможно было бы сделать присвоение свойствам этого объекта или вызвать метод объекта.

Т.е. внутри метода new() экземпляр объекта уже существует. Внутри метода new() объекта вполне допустимо обращение к методам этого объекта через this.MyMethod().

На всякий случай напомню, что речь идет о классах, а не о формах или отчетах.

Это означает, что конструирование объекта Axapta происходит ДО вызова метода new() этого же объекта. Просто разработчики Axapta предоставили возможность ПОСЛЕ конструирования объекта добавить некий код.

По сути, new() - это событие, т.е. некий программный код, который выполняется автоматически, при подаче команды new на создание объекта.

А вот метод init() - это именно метод. Т.е. некий программный код, который надо запускать на выполнение явно. Специальной командой. Автоматического выполнения метода init() никогда не происходит. Только явно по команде.

С точки зрения разработчика - нет никакой разницы где именно писать код инициализации параметров объекта. В событии new() объекта или в методе init().

Отличия между ними только и исключительно в способе вызова. Выполнение new() произойдет автоматически, а для выполнения init() надо подать специальную команду. Как следствие, выполнение init() можно отложить, чтобы выполнить, например, ряд проверок. Или же вызвать метод init() повтороно, для переинициализации всех свойств объекта. А выполнение new() отложить невозможно.

Следовательно, логично в событии new() объекта делать безусловную инициализацию свойств объекта (значения по умолчанию для переменных). А в методе init() выполнять "условную" инициализацию свойств с последующим анализом значения, возвращаемого этим методом для принятия решения о дальнейшей работе с этим объектом.


PS:

А насчет того, что переменная myVar не существует пока не будет завершена команда new MyObject(), так к обсуждаемой проблеме это не имеет никакого отношения.

То же самое будет и с любой переменной, значение которой вычисляется в каком-либо методе любого класса. Пока вычисления не завершены, естесственно, значение не известно.
За это сообщение автора поблагодарили: alex55 (1).
Старый 09.07.2008, 15:02   #8  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Как мне кажется, происходит путаница понятий. В системе Axapta создание объекта - это команда
X++:
myVar = new MyObject()
Кажется, что команда new вызывает непосредственно метод new() объекта. Однако если бы это было действительно так, то внутри метода new() объекта невозможно было бы сделать присвоение свойствам этого объекта или вызвать метод объекта.
Давайте, чтобы не создавать еще большую путаницу, немного уточним терминологию. Я применительно к языку Х++ не встречал упоминания термина "команда". В ОО-языках, таких как C++/C#, это называется оператор new; в том же С++ есть также операторы delete и delete[], служащие для освобождения выделенной под объект памяти, но в C#/X++ с их автоматических управлением памятью они не актуальны и, соответственно, отсутствуют. Еще в ОО-языках есть понятие конструкторов и деструкторов, которые вызываются, соответственно, при создании объекта (оператором new) и при его удалении (оператором delete, или сборщиком мусора, или еще кем). Путаница в случае Х++ возникает из-за того, что оператор new и конструктор new() называются одинаково; в моем предыдущем сообщении в этой теме, пожалуй, действительно смешались эти два понятия. Тем не менее, в Х++ вызов оператора new непосредственно ведет к вызову конструктора new().
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Т.е. внутри метода new() экземпляр объекта уже существует. Внутри метода new() объекта вполне допустимо обращение к методам этого объекта через this.MyMethod().
На мой взгляд, экземпляр объекта до завершения работы конструктора (а new() и finalize() в Х++ от прочих методов отличаются именно тем, что это конструктор и декструктор) все же не существует. Хотя, это вопрос философский: можно ли называть, к примеру, сооружение без крыши домом или конструкцию без двигателя - автомобилем?
К слову, в зависимости от реализации класса обращения к тем или иным методам внутри конструктора могут привести к некорректным результатам, если методы предполагают, что конструктор уже отработал, и какие-то внутренние структуры или объекты уже инициализированы - это опять же к вопросу о том, когда кусок выделенной памяти становится объектом.
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Это означает, что конструирование объекта Axapta происходит ДО вызова метода new() этого же объекта. Просто разработчики Axapta предоставили возможность ПОСЛЕ конструирования объекта добавить некий код.
Гхм... в моем понимании «конструирование объекта» осуществляется в общем случае его конструктором, а не, к примеру, оператором выделения памяти для объекта. И если объект не находится на вершине иерархии наследования, и при этом успели отработать лишь некоторые из конструкторов его базовых классов, то нельзя говорить о том, что объект уже создан. А в случае с классами в Аксапте иерархия наследования отнюдь не начинается с какого-либо класса, реализованого на Х++.
Если посмотреть, что происходит непосредственно в ядре, то увидим следующее:
  1. интерпретатор байт-кода (экземпляр класса interpret) встречает в байт-коде символ, соответствующий ключевому слову new и вызывает обработчик этого символа - метод interpret::xal_new_sym(void) (поскольку ядро написано на С++, будем здесь пользоваться нотацией этого языка);
  2. interpret::xal_new_sym(), в свою очередь, вызывает метод interpret::eval_new(cqlClass**,ushort), после чего инициализирует несколько полей созданного объекта;
  3. interpret::eval_new() сначала выделяет фиксированный объем памяти размером 56 (для AX3) или 60 (для AX4) байт, используя оператор new из библиотеки времени выполнения С++, который, в случае ядра Аксапты, вызывает соотв. метод выделения памяти библиотеки SmartHeap;
  4. после выделения памяти вызывается конструктор cqlClass::cqlClass(ushort), который заполняет выделенный участок памяти нулями и инициализирует некоторые служебные данные этого класса;
  5. затем увеличивается счетчик ссылок на сам созданный объект, а также глобальный счетчик ссылок, используемый, в частности, классом HeapCheck;
  6. наконец, происходит самое интересное - вызов конструктора new() создаваемого объекта, причем, поскольку все классы наследуют от Object, то констурктор вызывается всегда - либо определенный для данного класса или его предка, либо конструктор по умолчанию класса Object.
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
С точки зрения разработчика - нет никакой разницы где именно писать код инициализации параметров объекта. В событии new() объекта или в методе init().
В корне не согласен. Если рассматривать вопрос проектирования классов с точки зрения контрактной модели программирования, то инициализация объекта не может быть необязательной, если это не предусмотрено протоколом взаимодействия с объектом. Т.е., пользуясь данной терминологией, если инициализация объекта необходима для выполнения им контракта, а вы, проектируя и реализуя класс, даете возможность не выполнять эту инициализацию, то вы закладываете возможность нарушения объектом данного класса своего контракта при соблюдении протокола взаимодействия с ним.
По поводу контрактной модели см., например, Объектно-ориентированный анализ и проектирование Гради Буча.

Последний раз редактировалось gl00mie; 09.07.2008 в 15:12. Причина: typo
За это сообщение автора поблагодарили: mazzy (2), konopello (2), Evgeniy2020 (2).
Старый 09.07.2008, 15:13   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Это означает, что конструирование объекта Axapta происходит ДО вызова метода new() этого же объекта. Просто разработчики Axapta предоставили возможность ПОСЛЕ конструирования объекта добавить некий код.
Нет.
Инвариант: Конструирование объекта полностью завершено после завершения конструктора new().
Или, другими словами, объект становится валидным (целостным) после завершения конструктора new().

Другие утверждения не всегда истинны.

Если я правильно понимаю gl00mie, то он хочет сказать именно это.
__________________
полезное на axForum, github, vk, coub.
Старый 09.07.2008, 16:04   #10  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
Thumbs down
И хватает же у вас времени, господа, так активно дискутировать по такой незначительной теме... По-моему всем все давно понятно (ещё до этого поста). Играть словами можно до бесконечности и врядли это к чему-то полезному приведет. Может автор поста вообще закатил этот шар по-приколу...
Старый 09.07.2008, 16:13   #11  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
На самом деле - очень интересно, потому что видно, что даже самые "старые" участники форума не имеют четкого представления о том, как на самом деле что работает / должно работать.

И, возможно, полезно было бы прочитать последний ответ, в котором они бы сошлись во мнении конкретном, которое новички могли бы почитать и понять, что самое главное.
Старый 09.07.2008, 21:04   #12  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
gl00mie

К сожалению, я изучал ООП не по учебникам, а на практике, методом "научного тыка". Поэтому, для меня имеет реальное значение не то, как оно "должно быть" с точки зрения теории, а то, как оно есть на практике. Могут ли те или иные мои действия привести к проблемам или нет?

Собственно, насколько я понимаю, смысл Вашего сообщения сводится к тому, что в процессе выполнения конструктора new() данного объекта сам объект еще не завершен и, как следствие, некие действия с этим объектом могут закончится неудачей. Именно по той причине, что произойдет обращение к "не законченным частям" объекта.

На практике же я вижу, что таких конфликтов не происходит. Возможно, конечно, мне просто в голову не приходят такие действия, которые могут привести к конфликтам в данном случае.

А это значит, что вопрос именно философский. Не из цикла "что можно?", а из цикла "что дОлжно?". Поскольку, с точки зрения формального написания кода, какая-либо инициализация в конструкторе new() будет происходить точно так же, как и в любом другом методе объекта.
Старый 09.07.2008, 22:28   #13  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
На практике же я вижу, что таких конфликтов не происходит.
LedgerJournalEngine, LedgerVoucher, SalesType, SalesFormLetter, класс работы с принтером, классы работы с Vatiant'ами, FormBuild*, QueryBuild* и т.п... Даже простые формы... Тут конечно надо разобраться, но с огромной вероятностью, конфликт вы там получите.
__________________
полезное на axForum, github, vk, coub.
Старый 10.07.2008, 15:32   #14  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от mazzy Посмотреть сообщение
LedgerJournalEngine, LedgerVoucher, SalesType, SalesFormLetter, класс работы с принтером, классы работы с Vatiant'ами, FormBuild*, QueryBuild* и т.п... Даже простые формы... Тут конечно надо разобраться, но с огромной вероятностью, конфликт вы там получите.
Хм... Это предложение переписать стандартный функционал или подтверждение моих выводов?
Теги
init, crm2011

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Solutions Monkey: EP Page Life Cycle Blog bot DAX Blogs 0 18.02.2009 08:05
Не удаётся правильно настроить DataSource через метод init Dronas DAX: Программирование 1 08.10.2007 09:10
Два Dstasource с Range в init() PMS DAX: Программирование 7 28.10.2005 09:54
Метод Init на форме. NJD DAX: Программирование 1 25.08.2004 17:30
диалоговое окно в init (e) Report (a) Natasha DAX: Программирование 8 05.03.2003 16:42

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 01:07.