13.01.2005, 13:22 | #1 |
Участник
|
Зависимость порядка объявления переменных в classDeclaration
Доброго дня. Боюсь показаться неоригинальным, но всё же. Объясните, пожалуйста.
есть класс FactureJourCreate_RU, есть у него classDeclaration, есть метод new(). краткий листинг classDeclaration: abstract class FactureJourCreate_RU extends RunBaseBatch { Map mapInvoiceTrans; ..... Map vatCodeCache; } объявляю в classDeclaration переменную: abstract class FactureJourCreate_RU extends RunBaseBatch { Map mapInvoiceTrans; ..... ProjId projId; ..... Map vatCodeCache; } после этого выполнение метода new(): public void new() { super(); mapInvoiceTrans = new Map(Types::CONTAINER, Types::REAL); vatCodeCache = new Map(Types::CONTAINER, Types::STRING); unpackMap = true; showProgress = true; recalcTaxes = true; } падает на строке: vatCodeCache = new Map(Types::CONTAINER, Types::STRING); объявляю так: abstract class FactureJourCreate_RU extends RunBaseBatch { ProjId projId; Map mapInvoiceTrans; ..... Map vatCodeCache; } падает на строке: mapInvoiceTrans = new Map(Types::CONTAINER, Types::REAL); объявляю так: abstract class FactureJourCreate_RU extends RunBaseBatch { Map mapInvoiceTrans; ..... Map vatCodeCache; ProjId projId; } не падает. расскажите, почему так происходит. сидел полдня. всё перепробовал. решил поменять местами просто так, уже из отчаяния. и к моему большому удивлению помогло. не думал что от того, в каком месте я объявлю переменную что-то зависеть будет... заранее спасибо. |
|
13.01.2005, 13:53 | #2 |
----------------
|
после изменений в базовых классах (а класс abstract только таким и может быть) необходимо делать инкрементную компиляцию, чтобы все потомки узнали об этих нововведениях.
|
|
13.01.2005, 14:19 | #3 |
Участник
|
вообщем логично если метод new перекрыт в классе потомке и использует переменную базового класса, но здесь как я понимаю место где "падает" - метод new в самом базовом классе.
|
|
13.01.2005, 14:36 | #4 |
Модератор
|
Ну. А у потомков-то он не перекомпилирован! Не факт, что вызывается сам класс. Более того, учитывая то, что он абстрактный, вызывается как-раз кто-то из его потомков. Так инкриментная компиляция должна была помочь!
С Уважением, Георгий |
|
13.01.2005, 14:39 | #5 |
Дмитрий Ерин
|
Цитата:
Изначально опубликовано if_maks
но здесь как я понимаю место где "падает" - метод new в самом базовом классе. |
|
13.01.2005, 15:11 | #6 |
Участник
|
изменения коснулись не только classDeclaration. это к слову. перекомпиляция помогла. это два. но вопрос был в том, что если поставить переменную в начало classDeclaration, то "не работает", а если ставить в конец, то "всё работает" и без перекомпиляции... при чём тут порядок-то?? если всё дело только в перекомпиляции, то и при объявленной в конце classDaclaration переменной тож должно было "не работать"
|
|
13.01.2005, 15:44 | #7 |
Модератор
|
Блин! Код-то откомпилирован у потомков!
лежит где нибудь в памяти код: ПАПА_______________________ПОТОМОК адрес смещение переменная____адрес смещение переменная 00000 FF mapInvoiceTrans_______00000 FF mapInvoiceTrans 000FF FF vatCodeCache_________000FF FF vatCodeCache Вы добавляете код сюда:________потомок не перекомпилирован. 001FE 0А projId________________Но при вызове он может вызвать _____________________________метод откомпилированного родителя, _____________________________потому и не упадет с Run-time Error Теперь. Вы добавили код сюда: ПАПА_______________________ПОТОМОК адрес смещение переменная_____адрес смещение переменная 00000 FF mapInvoiceTrans________00000 FF mapInvoiceTrans Вы добавляете код сюда:_________000FF FF vatCodeCache 00109 0А projId_________________А в потомке - ссылка на СТАРЫЕ адреса!!! снова пошел старый код, но с новыми адресами 00208 FF vatCodeCache Поэтому при обращении к переменной vatCodeCache она обратиться к переменной, определенной в родителе по адресу 000FF. И что она там найдет?? кусок совершенно другой переменной! Поэтому и вылетает с Run-time error! Что у Вас, кстати, и произошло. Так чему здесь так удивляться? После инкриментной перекомпиляции: ПАПА_______________________ПОТОМОК адрес смещение переменная_____адрес смещение переменная 00000 FF mapInvoiceTrans________00000 FF mapInvoiceTrans 00109 0А projId_________________00109 0А projId 00208 FF vatCodeCache__________00208 FF vatCodeCache С Уважением, Георгий. Хм. При редактировании - все нормально. А после постинга пробелы форматирующие убрались |
|
|
За это сообщение автора поблагодарили: kashperuk (5). |
13.01.2005, 15:53 | #8 |
Участник
|
Георгий, скажите. почему тогда раньше при изменении мной кода методов классов такого не происходило. следуя вашим рассуждениям, такая ситуация должна посторяться каждый раз...
|
|
13.01.2005, 16:02 | #9 |
Модератор
|
Каждый раз, когда Вы поменяли родителя, у которого есть наследники и не сделали инкриментную или глобальную компиляцию.
Почему не произошло? 1) Не были затронуты те переменные, который идут за Вашей 2) Потомки переопределяли несколько методов которые не трогали переменные за Вашей. остольное вызывалось у базового класса, который откомпилирован. 3) Потомки часто не пользуют переменные напрямую, а только через параметр (типа parm...(parm _parm =parm)) 4) Вы могли откомпилировать как базовый класс, так и потомка ................ Но это - просто везение. Не стои так шутить. Инкриментная компиляция специально для этого случая и сделана. Если Вы так уже делали, то советую на всекий случать запусить глобальную. С Уважением, Георгий. |
|
Теги |
инкрементная компиляция, объявление переменной, наследование |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|