Comments 44
А еще есть замечательные методы BeforeDestruction и AfterConstruction
Почему-то у меня такое ощущение, что исключения принято вызывать, а возбуждают кой-чего другое. Но, если честно, Object Pascal использовал так давно, что не помню какой там для этого кейворд.
Зря на C++ бочку катите, посмотрите, как управление памятью в Qt реализовано
Никто не отрицает, что на С++ можно и нужно сделать (и неоднократно сделано!) хорошую реализацию управления памятью. Но речь шла о якобы очевидном поведении объектов C++ при создании и уничтожении. Ничего очевидного там, естественно, нет. Жесткий порядок вызова при инициализации, смертельная опасность выброса исключения из конструктора, перезапись указателя VMT, фактическая невиртуальность вызовов оттуда же…
Всё одна глава в книжке и всё это будете знать. После этого всё кажется очевидно :)
смертельная опасность выброса исключения из конструктораW-w-what?
Формулировка и впрямь слишком резкая. Точнее, бросать исключения из конструктора в C++ требует гораздо больше труда и внимательности, так как деструктор при этом вызван не будет, а неинициализированные части объекта содержат мусор. В результате за очистку при прерывании инициализации отвечает конструктор, не имея вдобавок простых средств для отделения зерна от плевел.
Со стороны C++-программиста на проблему можно посмотреть по ссылке: alenacpp.blogspot.com/2006/11/blog-post.html
Со стороны C++-программиста на проблему можно посмотреть по ссылке: alenacpp.blogspot.com/2006/11/blog-post.html
Деструкторы будут вызваны для всех полностью сконструированных членов класса и предков. Собственно главное — не бросать исключение в момент, когда какой-то объект находится в «промежуточном» состоянии. Для этого придумано RAII.
Соответственно, в деструкторе достаточно корректно обрабатывать нулевые значения, в чем сильно помогает процедура FreeAndNil, которая освобождает объект, только если ссылка на него уже не nil.
Точнее есть метод Free, который вызывает деструктор если Free был вызван для не нулевого объекта.
А процедура FreeAndNil еще дополнительно обнуляет объект который ей передали.
Точнее есть метод Free, который вызывает деструктор если Free был вызван для не нулевого объекта.
А процедура FreeAndNil еще дополнительно обнуляет объект который ей передали.
Да, имеет смысл упомянуть, что FreeAndNil еще и висячей ссылки за собой не оставляет.
Free не поминал специально, так как считаю его применение в деструкторах (и вообще везде, кроме тех мест где FreeAndNil задействовать невозможно) неправильным.
Почему — успешно объяснено до меня и без меня по ссылке: gunsmoker.blogspot.com/2009/04/freeandnil-free.html
Free не поминал специально, так как считаю его применение в деструкторах (и вообще везде, кроме тех мест где FreeAndNil задействовать невозможно) неправильным.
Почему — успешно объяснено до меня и без меня по ссылке: gunsmoker.blogspot.com/2009/04/freeandnil-free.html
Про эту ссылочку:
delphimaster.ru/cgi-bin/forum.pl?id=1256236718&n=3
Если интересно, могу и предыдущее обсуждение найти, конкретно про обсуждение данной ссылки
Ее уже здесь обсуждали, выяснили, что неполезная
delphimaster.ru/cgi-bin/forum.pl?id=1256236718&n=3
Если интересно, могу и предыдущее обсуждение найти, конкретно про обсуждение данной ссылки
Прочитал.
Участники дискуссии упускают из вида один важный момент (подробно освещенный по ссылке) — двойное удаление есть лишь частный случай использования висячей ссылки на объект, причем самый безобидный. Зато если после удаления будут вызваны любые другие методы объекта, то в случае использования FreeAndNil будет сразу возбуждено исключение, а Free эту ошибку замаскирует, причем наглухо — падать будет не всегда и совсем не там, где ошибка. Это куда более дорогая цена по сравнению с успешным двойным удалением (которое по факту все равно будет успешным однократным).
Участники дискуссии упускают из вида один важный момент (подробно освещенный по ссылке) — двойное удаление есть лишь частный случай использования висячей ссылки на объект, причем самый безобидный. Зато если после удаления будут вызваны любые другие методы объекта, то в случае использования FreeAndNil будет сразу возбуждено исключение, а Free эту ошибку замаскирует, причем наглухо — падать будет не всегда и совсем не там, где ошибка. Это куда более дорогая цена по сравнению с успешным двойным удалением (которое по факту все равно будет успешным однократным).
Почему-то мне кажется что топик несет в себе ноль полезной информации :(
В чем смысл-то? Перечисление «особенностей», о которых все знают?
В чем смысл-то? Перечисление «особенностей», о которых все знают?
возможность создания объектов с неизвестным на этапе компиляции классома можно пример?
Пример использования!
Фабрика объектов?
Фабрика объектов?
Пример из RTL Delphi. Этот код создает класс при десериализации его из потока.
procedure CreateComponent;
var
ComponentClass: TComponentClass;
begin
try
ComponentClass := FindComponentClass(CompClass);
Result := nil;
if Assigned(FOnCreateComponent) then
FOnCreateComponent(Self, ComponentClass, Result);
if Result = nil then
begin
Result := TComponent(ComponentClass.NewInstance);
if ffInline in Flags then
begin
Include(Result.FComponentState, csLoading);
Include(Result.FComponentState, csInline);
end;
try
Result.Create(Owner);
except
Result := nil;
raise;
end;
end;
Include(Result.FComponentState, csLoading);
except
if not Recover(Result) then raise;
end;
end;
Соответственно, в деструкторе достаточно корректно обрабатывать нулевые значения, в чем сильно помогает процедура FreeAndNil, которая освобождает объект, только если ссылка на него уже не nil.
Delphi 7:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
Об «очевидном» и полезном или создание и уничтожение Delphi
FIXED
FIXED
Delphi, ты еще жив?
В прошлом веке я так любил тебя. Ты был прекрасен.
В прошлом веке я так любил тебя. Ты был прекрасен.
Слухи о смерти Delphi оказались несколько преувеличены.
Хотя собственный родитель (Borland) приложил очень много усилий к организации «дельфицида».
Хотя собственный родитель (Borland) приложил очень много усилий к организации «дельфицида».
Одна из самых больших профессиональных ошибок в моей жизни — это то, что в далеком 92-93 году я сориентировался на Borland.
А ведь тогда _нужно_ было предолеть рвотный рефлекс и пересесть на MS. Тогда фаворит был неочевиден а среда Turbo/Delphi давала 100 очков форы MS.
Кто бы знал, что Borland, с его грандиозными планами, уйдет в маргиналии.
А ведь тогда _нужно_ было предолеть рвотный рефлекс и пересесть на MS. Тогда фаворит был неочевиден а среда Turbo/Delphi давала 100 очков форы MS.
Кто бы знал, что Borland, с его грандиозными планами, уйдет в маргиналии.
Вряд ли ошибка (если это именно ошибка) была совершена в 92-93 — Delphi вплоть до седьмой версии включительно был более чем на уровне.
Оптимальное время миграции — выход Delphi 8 под .NET. Именно тогда был взят гибельный курс. А вообще лично я не вижу проблемы для программиста с переходом на .NET и сейчас (если, конечно, нет жестких ограничений по времени и заработку прямо сейчас). И не наблюдаю реальных альтернатив Delphi для Win32.
Оптимальное время миграции — выход Delphi 8 под .NET. Именно тогда был взят гибельный курс. А вообще лично я не вижу проблемы для программиста с переходом на .NET и сейчас (если, конечно, нет жестких ограничений по времени и заработку прямо сейчас). И не наблюдаю реальных альтернатив Delphi для Win32.
>А вообще лично я не вижу проблемы для программиста с переходом на .NET и сейчас
Ключевое слово «сейчас». Тогда в 94 найти работу было крайне сложно. Пришлось преквалифицироваться. Потом еще раз, и еще раз и еще раз… Десктопных приложений с тех пор не писал.
А перескочить с php или perl на .NET достаточно сложно. К тому же длительный перерыв в професии дает о себе знать. Но если бы тогда сориентировался на богомерзкий MS VBasic вместо Delphi (1/2/3) жизнь могла бы пойти по другому. Так мне кажется.
Ключевое слово «сейчас». Тогда в 94 найти работу было крайне сложно. Пришлось преквалифицироваться. Потом еще раз, и еще раз и еще раз… Десктопных приложений с тех пор не писал.
А перескочить с php или perl на .NET достаточно сложно. К тому же длительный перерыв в професии дает о себе знать. Но если бы тогда сориентировался на богомерзкий MS VBasic вместо Delphi (1/2/3) жизнь могла бы пойти по другому. Так мне кажется.
Сопссно, C# — это прямой наследник Delphi (или младший брат, учитывая общего родителя :)
Меня глючит. Кто общий родитель С# и Delphi???????????????
Вспомнился старый анекдот про лекцию Вирта(Хансена) в испанояычном университете.
Вирта: Вам нравится языка Паскаль?
Студенты: Си, синьор! Си! (sí señor! sí!)
Я вообще-то алгол учил в свое время. И до сих пор скобки расставляю по алгольному.
Вспомнился старый анекдот про лекцию Вирта(Хансена) в испанояычном университете.
Вирта: Вам нравится языка Паскаль?
Студенты: Си, синьор! Си! (sí señor! sí!)
Я вообще-то алгол учил в свое время. И до сих пор скобки расставляю по алгольному.
Андерс Хейлсберг
channel9.msdn.com/shows/Behind+The+Code/Life-and-Times-of-Anders-Hejlsberg/
channel9.msdn.com/shows/Behind+The+Code/Life-and-Times-of-Anders-Hejlsberg/
Андерс Хейлсберг получил награду популярного журнала Dr. Dobb's Journal за создание Turbo Pascal, Delphi и C#.
Allen Bauer опубликовал в своём блоге заметку по данному поводу:
A case against FreeAndNil
A case against FreeAndNil
Все верно, от двойного удаления FreeAndNil не лечит, а маскирует.
Но любое другое использование висячей ссылки после освобождения маскирует уже Free, причем с куда худшими последствиями. Так что если код падает на Free, то сначала надо устранить двойное удаление, а уже потом заменить Free на FreeAndNil — для демаскировки использования висяка.
Но любое другое использование висячей ссылки после освобождения маскирует уже Free, причем с куда худшими последствиями. Так что если код падает на Free, то сначала надо устранить двойное удаление, а уже потом заменить Free на FreeAndNil — для демаскировки использования висяка.
Sign up to leave a comment.
Об «очевидном» и полезном или создание и уничтожение объектов Delphi