На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (495) « Первая ... 487 488 [489] 490 491 ...  494 495  ( Перейти к последнему сообщению )  
> Delphi vs C++ vs C# , ну и Java немножко, где-то ближе к старшему байту номеров страниц
    Цитата Chow @
    что мне надо знать что происходит в реализации родительских классов!


    Не обязательно знать, но вот ожидать - действительно надо. И действовать соответствующим образом
      Цитата --Ins-- @
      Не обязательно знать, но вот ожидать - действительно надо

      :D
        Цитата --Ins-- @
        Не обязательно знать, но вот ожидать - действительно надо. И действовать соответствующим образом

        И этот образ - это лишний код в стиле "кабы чего не вышло", да?
          Цитата Chow @
          где их нам надо?

          надо зачем?

          ExpandedWrap disabled
            procedure Base.Clear; // виртуальный
            begin
              // очистка Base
            end;
             
            destructor Base.Destroy; // виртуальный
            begin
               Clear;
               // удаление полей Base
            end;
             
            procedure Child.Clear;
            begin
              inherited;
              // очистка Child
            end;
             
            destructor Child.Destroy;
            begin
               inherited;
               // удаляем поля Child
            end;


          т.е. в данном случае предок и может и обращается к полям потомка
          но зачем это может понадобится предку? (child.destroy->base.destroy->child.clear->base.clear->[?])

          для этого примера:
          простота
          а для child и далее, удобство(в clear только очистка, в destroy только удаление)
          clear и destroy часть публичного интерфейса

          а как это будет в С++?
          я так понимаю clear будут у каждого свои(приватные) и + ещё один общий(публичный)?
          а в деструкторах надо заботится и об очистке и об удалении своего?
            Цитата Shaggy @
            а в деструкторах надо заботится и об очистке и об удалении своего?

            Да в плюсах, IMHO, вообще деструктор в таком случае не потребуется...
              Цитата MyNameIsIgor @
              Да в плюсах, IMHO, вообще деструктор в таком случае не потребуется...

              Да.

              Цитата Shaggy @
              надо зачем?

              М-да.. Вы меня таки не понимаете.
              Неужели предок не может обратиться к членам-данных (не к методам) которые он унаследовал от родителя?
              Может конечно.
              Тем более никто ж не запрещает это обращение делать в деструкторе ведь правда?
              (ну например что-бы залогировать состояние какого-то унаследованого поля, а базовый клас этого логирования не делает).
              Как ж быть тогда если, как вы предалагали, раскрутить цепочку родительских деструкторов ДО своего деструктора?
                Цитата Shaggy @
                а как это будет в С++?

                Можно несколько раскрыть "это"?
                  Цитата Chow @
                  (ну например что-бы залогировать состояние какого-то унаследованого поля, а базовый клас этого логирования не делает).
                  Как ж быть тогда если, как вы предалагали, раскрутить цепочку родительских деструкторов ДО своего деструктора?

                  ExpandedWrap disabled
                    destructor XXX.Destroy;
                    begin
                       // запись в лог
                      inherited;
                      // удаление своего
                    end;
                  Сообщение отредактировано: Shaggy -
                    Shaggy, т.е. мне каждый раз при написании деструктора любого класа надо напрягать моск и думать куда именно в теле деструктора следует воткнуть inherited; только ради того что-бы "кабы чего не вышло"? :blink:

                    Добавлено
                    Более того? Кто за меня перевоткнет этот inherited; в другое место в случае если реализация базового класа поменяется, а я об этом и знать не буду??
                      Shaggy
                      Ты выкручиваешься как уж на сковородке ;) Хотя лучше\честнее было бы признать, что юзать в деструкторе виртуальные методы общего назначения (такие как Clear) - это мягко говоря, не гуд, а грубо говоря, за такие штучки надо бы руки отрывать (в том числе и самим борманам за их TList). Хоть бы предупредительный комментарий в заголовочник включили, если без подобных опусов никак.
                      В данном случае, когда не хочется дублировать код виртуального Clear надежнее использовать дополнительный невиртуальный фантик, ну или костылик, если хотите :)
                      ExpandedWrap disabled
                        procedure Base.DoClear; //НЕ виртуальный, приватный
                        begin
                           //очистка Base
                        end;
                         
                        procedure Base.Clear; //виртуальный, публичный
                        begin
                           DoClear;
                        end;
                         
                        destructor Base.Destroy; //виртуальный
                        begin
                           DoClear; //НЕ виртуальная очистка только Base
                           // удаление полей Base
                        end;
                        Цитата Chow @
                        Более того? Кто за меня перевоткнет этот inherited; в другое место в случае если реализация базового класа поменяется, а я об этом и знать не буду??


                        Chow, в твоих силах написать свой потомок так, что от реализации базового класса он зависеть не будет. Если используешь объекты в своих виртуальных методах (особенно с красноречивым названием Clear) ты в принципе можешь не торопиться с его уничтожением, даже не проверяя, как и где деструктор предка этот метод вызывает
                          PS: Когда я говорю о допустимости использования виртуальных методов в конструкторах для кастомизации\полиморфизма и т.п., то имею в виду специально предусмотренные для этого методы с понятным недвусмысленным названием и описанием того, что они могут\должны делать. В той же TForm.Create неявно вызываются методы Loaded всех загруженных в форму компонентов, и в справке четко оговаривается для чего они м.б. использованы и в каком порядке вызываются.
                          Сообщение отредактировано: leo -
                            Цитата Shaggy @
                            destructor XXX.Destroy;
                            begin
                            // запись в лог
                            inherited;
                            // удаление своего
                            end;

                            И да, в этом случае не буде произведена запись в лог _финального_ состояния члена-данных, так как после логирования вполне возможно оно еще изменится в недрах родительских конструкторов и мы эти изменения потеряем (для лога).
                              Цитата Chow @
                              Shaggy, т.е. мне каждый раз при написании деструктора любого класа надо напрягать моск и думать куда именно в теле деструктора следует воткнуть inherited; только ради того что-бы "кабы чего не вышло"?

                              перекрыл виртуальный метод, посмотри в деструктор
                              по моему просто...

                              Цитата Chow @
                              Более того? Кто за меня перевоткнет этот inherited; в другое место в случае если реализация базового класа поменяется, а я об этом и знать не буду??

                              поменяется как? пример можно?

                              Цитата leo @
                              Ты выкручиваешься как уж на сковородке

                              а меня кто-то к стенке прижал?

                              Цитата leo @
                              Хотя лучше\честнее было бы признать, что юзать в деструкторе виртуальные методы общего назначения (такие как Clear) - это мягко говоря, не гуд, а грубо говоря, за такие штучки надо бы руки отрывать (в том числе и самим борманам за их TList). Хоть бы предупредительный комментарий в заголовочник включили, если без подобных опусов никак.

                              почему?
                              всё что нужно знать это:
                              в конструкторе:
                              предок не может вызвать виртуальные методы до inherited Create;
                              в деструкторе:
                              предок не может вызывать после inherited Destroy
                              всё

                              Цитата leo @
                              В данном случае, когда не хочется дублировать код виртуального Clear надежнее использовать дополнительный невиртуальный фантик, ну или костылик, если хотите

                              в каждом наследнике ты добавляешь один приватный метод и перекрываешь виртуальный
                              а я перекрываю один виртуальный метод


                              Цитата D_KEY @
                              Можно несколько раскрыть "это"?

                              Цитата MyNameIsIgor @
                              Да в плюсах, IMHO, вообще деструктор в таком случае не потребуется...

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

                              Добавлено
                              Цитата Chow @
                              И да, в этом случае не буде произведена запись в лог _финального_ состояния члена-данных, так как после логирования вполне возможно оно еще изменится в недрах родительских конструкторов и мы эти изменения потеряем (для лога).

                              каких конструкторов? мы в деструкторе находимся
                              и каким образом изменится? запись в лог повлияет на состояние объекта что-ли?
                              Сообщение отредактировано: Shaggy -
                                Цитата Shaggy @
                                всё что нужно знать это:
                                в конструкторе:
                                предок не может вызвать виртуальные методы до inherited Create;
                                в деструкторе:
                                предок не может вызывать после inherited Destroy
                                всё

                                Вроде логично, но теперь глянь в справку и посмотри чему учат школьников на образцовых примерах с пояснениями
                                Цитата
                                The last action in a destructor's implementation is typically to call the inherited destructor to destroy the object's inherited fields.

                                Так где зарыт источник косяков, в "бестолковой" справке, или в "бестолковы[" разработчиках, не читающих справки и сующих виртуальные Clear в деструктор, делая его не typically-наследуемым?

                                Добавлено
                                В догонку Flex Ferrum
                                Цитата Flex Ferrum @
                                Низкий порог входа подразумевает, что среда (её дизайн) предполагают, что школьник при всём своём желании не налажает. ...
                                Тебе фреймворк и язык не позволяют (ну, по крайней мере, я так наивно считаю) совершать грубые ошибки. И это, в общем то, правильно. Так ведь?

                                Не совсем так. Всех желаний пытливо-шаловливых школьников предугадать невозможно, и как, я уже говорил, раздел "С\С++: Общие вопросы" пестрит школьными казусами ничуть не меньше, чем дельфийский. Просто мы тут ухватились за одну частную проблему и грызем ее до посинения, а если начать считать косяки и грабли, на которые могут нарваться начинающие, то еще неизвестно в чью пользу счет будет. Хотя у вас всегда найдется отмазка - ткнуть школьника носом в пункт №x.x.x.(x) вашего запу(нк)танного стандарта и послать читать "букварь" :). В дельфийской справке тоже все расписано и разжевано со всеми Note и Warning, только почему-то в нашем (формошлепском ?!) сообществе не принято ее штудировать "от корки до корки", и соотв-но и школьников мало кто и редко когда тыкает носом - "мы все учились понемногу чему-нибудь, и как-нибудь.." :(

                                Цитата Flex Ferrum @
                                Если заполнение этого свойства считается обязательным, почему дизайн среды заставляет пользователя указывать его явно в своём коде?

                                Обязательным параметром считается только Owner, который и указывается в конструкторе. Для нас Азы, для вас "история болезни" :) - дизайн среды в первую очередь заточен на автоматическое создание компонентов из ресурсов, поэтому все компоненты, как видимые (имеющие Parent), так и невидимые имеют единый виртуальный конструктор с единственным параметром Owner, а все прочие свойства, в т.ч. и Parent, устанавливаются уже после создания компонента. Посему, создание кнопки в рантайме - это уже "продвинутая" технология, для использования которой нужны минимальные знания о том, чем отличаются Owner и Parent, и за что они отвечают. Все это достаточно подробно расписано в справке, поэтому most often forgotten может происходить не по причине банальной невнимательности, а скорее из-за полного непонимания того, что делаешь.

                                PS: Хотя справедливости ради, стоит заметить, что для визуальных контролов можно было бы в конструкторе пытаться автоматом устанавливать Parent = Owner (через тот же SetParentComponent), но отцы-основатели решили этого не делать - значит, им виднее ;) К тому же для школьника, на мой взгляд, было бы проще запомнить, что недостаточно просто создать контрол, а нужно его еще вставить в требуемый визуальный контейнер вызовом метода InsertControl() этого контейнера (= привычная практика для любых контейнеров). Ан, нет, отцы решили, что InsertControl будет у нас частным методом, а универсальным и рекомендуемым к использованию св-во Parent, хотя для новичков присвоение Parent:=... в выше приведенном коде теряется среди "сотни других" аналогичных присваиваний, и они не сразу запоминают, что Parent - это и есть самое важное и необходимое
                                Сообщение отредактировано: leo -
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 487 488 [489] 490 491 ...  494 495


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,3900 ]   [ 14 queries used ]   [ Generated: 20.05.24, 18:40 GMT ]