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

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

    существует класс X(для простоты будем считать его списком)
    у него есть виртуальный метод clear, который(кто бы мог подумать) чистит список
    и есть деструктор, который перед собственно удалением очищает список, для чего вызыват метод clear
    что вполне логично(зачем дублировать код?)
    и всё работает, работает правильно

    и тут появляется Chow
    он создаёт класс Y, наследуясь от X
    добавляет новое поле F(которое тоже для простоты будем считать списком)
    которое в конструкторе инициализирует, т.е. создаёт объект
    а в деструкторе соответственно объект удаляет
    также он перекрывает метод clear
    в котором почему-то не чистит внутренний список, а удаляет его
    причём F у него совсем не reference, как было бы в delphi, а очень даже value т.е. даже нельзя определить в каком состоянии находится поле(?), создан объект или нет

    и вот экземпляр Y создан
    и даже работает... до первого вызова clear()
    а при уничтожении экземпляра выскакивает AV

    [сарказм]а виноваты конечно виртуальные методы, вызываемые из деструктора, объектная модель, и сам билдер[/сарказм]

    а всего-то надо было использовать clear по назначению, т.е. чистить внутренний список, а не удалять
      Shaggy, это ты так и не понял.

      Цитата Shaggy @
      также он перекрывает метод clear
      в котором почему-то не чистит внутренний список, а удаляет его

      Нет. Я его чищу и не удаляю.

      Цитата Shaggy @
      причём F у него совсем не reference, как было бы в delphi, а очень даже value т.е. даже нельзя определить в каком состоянии находится поле(?), создан объект или нет

      Это не важно, а во вторых, допустим даже и reference. Что меняет?

      Цитата Shaggy @
      и вот экземпляр Y создан
      и даже работает... до первого вызова clear()

      Неправда. Работает до УДАЛЕНИЯ объекта. А сам clear() хоть стопицот раз вызывай - все норм. Пока объект жив - все отлично.

      Проблема в том, что я в деструкторе своего класса после удаления списка не заNil`ивал reference на него - ибо я и знать не мог что после деструктора мне этот reference на список еще может понадобиться.
      А привычки "на всякий случай" заNil`ивать - не имею.

      Добавлено
      Цитата Shaggy @
      а всего-то надо было использовать clear по назначению, т.е. чистить внутренний список, а не удалять

      [сарказм]Спасибо КЭП, какой же я бестолковый - даже и не знал каково назначение метода clear[/сарказм]
        Chow, +1 :D
          Цитата Chow @
          Проблема в том, что я в деструкторе своего класса после удаления списка не заNil`ивал reference на него - ибо я и знать не мог что после деструктора мне этот reference на список еще может понадобиться.
          А привычки "на всякий случай" заNil`ивать - не имею.

          если всё так, то заnilивание тебе не поможет, т.к. в clear будет обращение к удалённому объекту

          1. надо создавать объект до первого обращения к нему и удалять только после использования
          2. в конструкторе и деструкторе можно вызывать любые методы, а следовательно обратиться к любомо полю
          3. а раз так то см.1 и решение простое как три копейки:

          ExpandedWrap disabled
            constructor XXX.Create;
            begin
              F:=YYY.Create;
              inherited;
            end;
             
            destructor XXX.Destroy;
            begin
              inherited;
              F.Free;
            end;


          и никаких проверок и заниливаний не нужно

          PS. почему-то был уверен, что ты удаляешь список в clear, перечитал сообщения и не нашёл
          приношу свои извинения, был не прав
            Цитата Shaggy @
            надо создавать объект до первого обращения к нему и удалять только после использования

            Ну так откуда ему было знать, что его дернут после того, как он удалил объект в деструкторе ;) ?
              Shaggy, у него с++ :D Приходится костылить, таким образом inherited не напишешь
                Цитата Shaggy @
                если всё так, то заnilивание тебе не поможет, т.к. в clear будет обращение к удалённому объекту

                Поможет (наверное) если я в clear перед тем как обратиться к списку буду проверять на nil тот reference на список.
                Т.е. с помощью: дополнительного if-а в методе clear (который по сути там не нужен и при нормальной работе объекта будет просто кушать лишние такты), заnilиванием referenc`а на список в деструкторе и ментальным неудовлетворением от того что в методе clear будет происходить доступ к члену-данных класса который уже разрушен и сейчас разрушается родительский класс - проблему, думаю, решить можно.

                Ага. И еще с одним ограничением, что мой список должен быть теперь только как reference (указатель), т.е. впервые в жизни пришлось бы написать дикую конструкцию:
                ExpandedWrap disabled
                  std::list<int>* myList;
                  Chow, твоя проблема не виртуальном деструкторе, а в том привете, который тебе Крайзер передавал как пользователю билдера ;)
                    Цитата --Ins-- @
                    Shaggy, у него с++ :D Приходится костылить, таким образом inherited не напишешь

                    Эм. С++ не вызовет виртуальный метод из деструктора.
                      Цитата D_KEY @
                      С++ не вызовет виртуальный метод из деструктора.

                      А недобилдер? :lol:
                        Цитата MyNameIsIgor @
                        Цитата D_KEY @
                        С++ не вызовет виртуальный метод из деструктора.

                        А недобилдер? :lol:

                        Очевидно, что если вызывает, то он не С++ :)
                          Цитата Shaggy @
                          3. а раз так то см.1 и решение простое как три копейки:

                          Т.е. у Делфистов нормальная практика сначала раскручивать вызовы родительских деструкторов а потом выполнять свой опять же по принципу "кабы чего не вышло"?
                          Тем более так можна стать на те же грабли только с другой стороны: что если уже в своем классе внезапно нужен доступ к членам-данных родительского(их) класса? Как быть? Мы ж уже раскрутили цепочку деструкторов и гарантировано они уже все похерились и тут мы попадаем в свой деструктор где их нам надо?
                            Цитата D_KEY @
                            Ну так откуда ему было знать, что его дернут после того, как он удалил объект в деструкторе

                            ему не надо это знать
                            ему надо знать прямо противоположную вещь

                            он дал предку возможность влиять на потомка(перекрыл виртуальный метод)
                            он знал когда предок мог этим влиянием точно уже не воспользуется

                            Цитата D_KEY @
                            Эм. С++ не вызовет виртуальный метод из деструктора.

                            не вызовет в принципе или вызовет как обычный метод?
                              Цитата Shaggy @
                              ему не надо это знать

                              Ну вот он и попытался не знать. Не получилось :)

                              Цитата
                              не вызовет в принципе или вызовет как обычный метод?

                              Как метод с ранним связыванием. Поскольку деструктор базового класса будет выполняться уже после разрушения потомка.
                                Цитата --Ins-- @
                                Chow, твоя проблема не виртуальном деструкторе, а в том привете, который тебе Крайзер передавал как пользователю билдера

                                В общем - да, согласен. Но суть не в том.. Даже если я и знаю (а я знал) эту особеность как вы тут выразились недобилдера меня напрягает то, что мне надо знать что происходит в реализации родительских классов! Вот что напрягает в Делфи. Хорошо что я посмотрел (слава торрентам) и понял откуда ноги растут (а костыли - дело другорядное), но вот как быть если не было, я не учел, а потом проапдейтив библиотеку и там появилось? Как мне об этом узнать?
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 486 487 [488] 489 490 ...  494 495


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.6298 ]   [ 14 queries used ]   [ Generated: 28.07.26, 13:12 GMT ]