Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 486 487 [488] 489 490 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#7306
,
|
|
|
|
Цитата Chow @ А выходит что надо, потому что если я перегружаю хоть один виртуальный метод своего предка то я уже просто обязан FreeAndNil`ить все члены-данных своего класса в своем деструкторе на всяк случай ибо фиг его знает, а вдруг кто-то из предков в своем деструкторе вызывает виртуальный метод? да не обязан же... ты так и не понял, что я тебе говорил написал говнокод который вполне закономерно падает и делаешь далеко идущие выводы по порядку: существует класс X(для простоты будем считать его списком) у него есть виртуальный метод clear, который(кто бы мог подумать) чистит список и есть деструктор, который перед собственно удалением очищает список, для чего вызыват метод clear что вполне логично(зачем дублировать код?) и всё работает, работает правильно и тут появляется Chow он создаёт класс Y, наследуясь от X добавляет новое поле F(которое тоже для простоты будем считать списком) которое в конструкторе инициализирует, т.е. создаёт объект а в деструкторе соответственно объект удаляет также он перекрывает метод clear в котором почему-то не чистит внутренний список, а удаляет его причём F у него совсем не reference, как было бы в delphi, а очень даже value т.е. даже нельзя определить в каком состоянии находится поле(?), создан объект или нет и вот экземпляр Y создан и даже работает... до первого вызова clear() а при уничтожении экземпляра выскакивает AV [сарказм]а виноваты конечно виртуальные методы, вызываемые из деструктора, объектная модель, и сам билдер[/сарказм] а всего-то надо было использовать clear по назначению, т.е. чистить внутренний список, а не удалять |
|
Сообщ.
#7307
,
|
|
|
|
Shaggy, это ты так и не понял.
Цитата Shaggy @ также он перекрывает метод clear в котором почему-то не чистит внутренний список, а удаляет его Нет. Я его чищу и не удаляю. Цитата Shaggy @ причём F у него совсем не reference, как было бы в delphi, а очень даже value т.е. даже нельзя определить в каком состоянии находится поле(?), создан объект или нет Это не важно, а во вторых, допустим даже и reference. Что меняет? Цитата Shaggy @ и вот экземпляр Y создан и даже работает... до первого вызова clear() Неправда. Работает до УДАЛЕНИЯ объекта. А сам clear() хоть стопицот раз вызывай - все норм. Пока объект жив - все отлично. Проблема в том, что я в деструкторе своего класса после удаления списка не заNil`ивал reference на него - ибо я и знать не мог что после деструктора мне этот reference на список еще может понадобиться. А привычки "на всякий случай" заNil`ивать - не имею. Добавлено Цитата Shaggy @ а всего-то надо было использовать clear по назначению, т.е. чистить внутренний список, а не удалять [сарказм]Спасибо КЭП, какой же я бестолковый - даже и не знал каково назначение метода clear[/сарказм] |
|
Сообщ.
#7308
,
|
|
|
|
Chow, +1
|
|
Сообщ.
#7309
,
|
|
|
|
Цитата Chow @ Проблема в том, что я в деструкторе своего класса после удаления списка не заNil`ивал reference на него - ибо я и знать не мог что после деструктора мне этот reference на список еще может понадобиться. А привычки "на всякий случай" заNil`ивать - не имею. если всё так, то заnilивание тебе не поможет, т.к. в clear будет обращение к удалённому объекту 1. надо создавать объект до первого обращения к нему и удалять только после использования 2. в конструкторе и деструкторе можно вызывать любые методы, а следовательно обратиться к любомо полю 3. а раз так то см.1 и решение простое как три копейки: ![]() ![]() constructor XXX.Create; begin F:=YYY.Create; inherited; end; destructor XXX.Destroy; begin inherited; F.Free; end; и никаких проверок и заниливаний не нужно PS. почему-то был уверен, что ты удаляешь список в clear, перечитал сообщения и не нашёл приношу свои извинения, был не прав |
|
Сообщ.
#7310
,
|
|
|
|
Цитата Shaggy @ надо создавать объект до первого обращения к нему и удалять только после использования Ну так откуда ему было знать, что его дернут после того, как он удалил объект в деструкторе ? |
|
Сообщ.
#7311
,
|
|
|
|
Shaggy, у него с++
Приходится костылить, таким образом inherited не напишешь |
|
Сообщ.
#7312
,
|
|
|
|
Цитата Shaggy @ если всё так, то заnilивание тебе не поможет, т.к. в clear будет обращение к удалённому объекту Поможет (наверное) если я в clear перед тем как обратиться к списку буду проверять на nil тот reference на список. Т.е. с помощью: дополнительного if-а в методе clear (который по сути там не нужен и при нормальной работе объекта будет просто кушать лишние такты), заnilиванием referenc`а на список в деструкторе и ментальным неудовлетворением от того что в методе clear будет происходить доступ к члену-данных класса который уже разрушен и сейчас разрушается родительский класс - проблему, думаю, решить можно. Ага. И еще с одним ограничением, что мой список должен быть теперь только как reference (указатель), т.е. впервые в жизни пришлось бы написать дикую конструкцию: ![]() ![]() std::list<int>* myList; |
|
Сообщ.
#7313
,
|
|
|
|
Chow, твоя проблема не виртуальном деструкторе, а в том привете, который тебе Крайзер передавал как пользователю билдера
|
|
Сообщ.
#7314
,
|
|
|
|
Цитата --Ins-- @ Shaggy, у него с++ Приходится костылить, таким образом inherited не напишешьЭм. С++ не вызовет виртуальный метод из деструктора. |
|
Сообщ.
#7315
,
|
|
|
|
Цитата D_KEY @ С++ не вызовет виртуальный метод из деструктора. А недобилдер? |
|
Сообщ.
#7316
,
|
|
|
|
Цитата MyNameIsIgor @ Цитата D_KEY @ С++ не вызовет виртуальный метод из деструктора. А недобилдер? ![]() Очевидно, что если вызывает, то он не С++ |
|
Сообщ.
#7317
,
|
|
|
|
Цитата Shaggy @ 3. а раз так то см.1 и решение простое как три копейки: Т.е. у Делфистов нормальная практика сначала раскручивать вызовы родительских деструкторов а потом выполнять свой опять же по принципу "кабы чего не вышло"? Тем более так можна стать на те же грабли только с другой стороны: что если уже в своем классе внезапно нужен доступ к членам-данных родительского(их) класса? Как быть? Мы ж уже раскрутили цепочку деструкторов и гарантировано они уже все похерились и тут мы попадаем в свой деструктор где их нам надо? |
|
Сообщ.
#7318
,
|
|
|
|
Цитата D_KEY @ Ну так откуда ему было знать, что его дернут после того, как он удалил объект в деструкторе ему не надо это знать ему надо знать прямо противоположную вещь он дал предку возможность влиять на потомка(перекрыл виртуальный метод) он знал когда предок мог этим влиянием точно уже не воспользуется Цитата D_KEY @ Эм. С++ не вызовет виртуальный метод из деструктора. не вызовет в принципе или вызовет как обычный метод? |
|
Сообщ.
#7319
,
|
|
|
|
Цитата Shaggy @ ему не надо это знать Ну вот он и попытался не знать. Не получилось Цитата не вызовет в принципе или вызовет как обычный метод? Как метод с ранним связыванием. Поскольку деструктор базового класса будет выполняться уже после разрушения потомка. |
|
Сообщ.
#7320
,
|
|
|
|
Цитата --Ins-- @ Chow, твоя проблема не виртуальном деструкторе, а в том привете, который тебе Крайзер передавал как пользователю билдера В общем - да, согласен. Но суть не в том.. Даже если я и знаю (а я знал) эту особеность как вы тут выразились недобилдера меня напрягает то, что мне надо знать что происходит в реализации родительских классов! Вот что напрягает в Делфи. Хорошо что я посмотрел (слава торрентам) и понял откуда ноги растут (а костыли - дело другорядное), но вот как быть если не было, я не учел, а потом проапдейтив библиотеку и там появилось? Как мне об этом узнать? |