Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 395 396 [397] 398 399 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#5941
,
|
|
|
|
Цитата IL_Agent @ Я, например, использовал однажды. Надо было создавать базу, а потом она должна была удаляться... Ну, ok, а если GC так и не доберётся до этого объекта? База так и останется незакрытой? |
|
Сообщ.
#5942
,
|
|
|
|
Цитата IL_Agent @ Я, например, использовал однажды. Надо было создавать базу, а потом она должна была удаляться... Так должна была, или не очень должна? |
|
Сообщ.
#5943
,
|
|
|
|
Цитата amk @ В Python'е используется управление памятью на основе счетчиков ссылок, поэтому объект разрушается сразу, как только на него исчезает последняя ссылка. Кроме того в питоне объект может иметь деструктор (специальный метод __del__), поэтому для этого языка тоже возможно нормальное использование RAII. Ссылки правда там пропадают только при выходе из функции, поэтому гибкость хуже, чем в C++. С другой стороны, если объект оказывается включен в циклическую структуру, он может быть вычищен сборщиком мусора. Правда наличие деструктора может помешать в таком случае удалить объект. Собственно, ничто не мешает программировать на питоне без использования finally. А если ссылка передается во вне функции и хранится где-то до завершения работы программы? Нет, я не стал бы полагаться на такую особенность в Питоне, она только запутывает и создает лишь иллюзию возможности обойтись без try-finally, а не реальную возможность. Все-таки, если есть GC, то ресурсы, которые нужно особождать в определенное время, лучше освобождать явно. Кроме того, вдруг Гвидо захочет сделать копирующий GC, то весь код, написанный с этим подобием RAII, придется переписывать. Кстати, помните, мы обсуждали уродство вложенных try-finally/try-except в Делфи при создании нескольких объектов последовательно? Напомню: ![]() ![]() procedure Awful; var x : TX; y : TY; z : TZ; begin x := TX.Create; try y := TY.Create; try z := TZ.Create; try // полезный код finally z.Free; end; finally y.Free; end; finally z.Free; end; end; И это еще без except, который также приходится вкладывать, если нам нужно что-то делать только при возникновении исключения, а что-то в обоих случаях. В общем тут у Делфи наверное хуже всех синтаксис, то ли дело Руби, но я не об этом... =) Недавно прочитал про освобождение ресурсов в Go, там вышеприведенный код выглядел бы так: ![]() ![]() func Nice() { var x := X() defer x.Free() var y := Y() defer y.Free() var z := Z() defer z.Free() // полезный код } Т.е. defer-выражения гарантированно вызовятся при выходе из процедуры Nice. Не идеал, но заметно лучше. Естественно y.Free(), например, не вызовется, если исключение возникло выше по коду. |
|
Сообщ.
#5944
,
|
|
|
|
Цитата korvin @ Недавно прочитал про освобождение ресурсов в Go Содрано с плюсов |
|
Сообщ.
#5945
,
|
|
|
|
Цитата D_KEY @ Ну фактически так. Его дергает GC Поскольку он дергается из GC, то и зависит все от того, как этот самый GC работает, как часто вызывается, много ли памяти, часто ли создаются объекты и т.п. В общем случае нельзя утверждать, что финализатор будет вызван вообще, поскольку при определенных обстоятельствах(малой интенсивности создания объектов и большом объеме свободной памяти) GC может или быть вообще не вызван, или не дойдет до нашего объекта(например, при сборке с поколениями). Ну так гугл ж А так - метод, который дергается GC перед освобождением памяти, выделенной под объект. Гм... Ясно, я почему-то подумал, что GC вызывает утилизацию для каждого объекта в отдельности, но сейчас вспомнил принцип работы копирующего GC и понял свою ошибку =) Добавлено Цитата MyNameIsIgor @ Содрано с плюсов ![]() Почему? Это можно и назвать "содранным с try-finally <любой язык с try-finally> с раскидкой по коду". Собственно это не важно, пусть будет с плюсов. Добавлено Но ведь это освобождение может и не быть вызвано, как мне тут D_KEY подсказал, что тогда? |
|
Сообщ.
#5946
,
|
|
|
|
Цитата korvin @ Почему? ![]() ![]() class defer { public: template<typename F> defer(F&& f) : f_(std::forward<F>(f)) {} ~defer() { f_(); } private: std::function<void ()> f_; }; void Nice() { X x; defer d1([&x] { x.Free(); }); Y y; defer d2([&y] { y.Free(); }); Z z; defer d3([&z] { z.Free(); }); // полезный код } Многословнее, конечно, но без поддержки в компиляторе, а семантика та же самая. Добавлено Цитата korvin @ Собственно это не важно, пусть будет с плюсов. Это важно в контексте того обсуждения, где доказывалось, что finally - костыль |
|
Сообщ.
#5947
,
|
|
|
|
Цитата MyNameIsIgor @ Цитата korvin @ Почему? ![]() ![]() class defer { public: template<typename F> defer(F&& f) : f_(f) {} ~defer() { f_(); } private: std::function<void ()> f_; }; void Nice() { X x; defer d1([&x] { x.Free(); }); Y y; defer d2([&y] { y.Free(); }); Z z; defer d3([&z] { z.Free(); }); // полезный код } Многословнее, конечно... То что ты изобразил на Плюсах тоже, что и представленно в коде Go, не говорит о том, что это содрано с Плюсов. Зачем ты вообще это сделал, если в Плюсах есть RAII и нет необходимости в этой многословности? Я вполне согласен, что прием, реализованный в Go напоминает RAII, лишь с добавлением defer-выражений, ибо иначе в языке с GC никак. Может даже авторы Go действительно реализовывали этот прием с оглядкой на Плюсы, хотя Пайк и негативно о них отзывался. Может даже меня глючит, но почему-то в памяти всплывает, будто он говорил, что это они взяли как раз с Плюсов. Цитата MyNameIsIgor @ но без поддержки в компиляторе, а семантика та же самая. А, т.е. следующий код требует поддержки со стороны компилятора и не гарантируется стандартом: ![]() ![]() class X { public: X() {}; ~X() {}; }; ... // Y and Z classes void Nice() { X x; Y y; Z z; // полезный код } ? |
|
Сообщ.
#5948
,
|
|
|
|
Цитата MyNameIsIgor @ А это пришлось доказывать? O_o Это важно в контексте того обсуждения, где доказывалось, что finally - костыль |
|
Сообщ.
#5949
,
|
|
|
|
Цитата MyNameIsIgor @ Это важно в контексте того обсуждения, где доказывалось, что finally - костыль ![]() В C++ может быть и костыль, но в языках с GC без него никак. Другое дело, что он не везде достаточно удобен в использовании. =) Добавлено Поэтому над твоей фразой нужно провести замену: s/костыль/костыль в Делфи/g Добавлено Какое интересное совпадение: в Делфи finally — костыль и в нем же он наименее удобен... |
|
Сообщ.
#5950
,
|
|
|
|
Цитата korvin @ Зачем ты вообще это сделал, если в Плюсах есть RAII и нет необходимости в этой многословности? Цитата korvin @ А, т.е. следующий код требует поддержки со стороны компилятора и не гарантируется стандартом Есть, например, мьютексы. Тогда вместо создания переменных будет lock() и unlock() в defer. Цитата korvin @ Я вполне согласен, что прием, реализованный в Go напоминает RAII, лишь с добавлением defer-выражений, ибо иначе в языке с GC никак. Ну, например, в D решили так же, только их аналог зовётся кивордом scope. А вот в C++/CLI Саттер вполне красиво обошёлся без ключевых слов для .NET-классов. Цитата korvin @ То что ты изобразил на Плюсах тоже, что и представленно в коде Go, не говорит о том, что это содрано с Плюсов. Цитата korvin @ Может даже меня глючит, но почему-то в памяти всплывает, будто он говорил, что это они взяли как раз с Плюсов. ![]() Да и вообще, я только рад за Go, что они так сделали - ещё один камень в finally. Добавлено Цитата korvin @ В C++ может быть и костыль, но в языках с GC без него никак. Dunno, C++/CLI как-то обошёлся... |
|
Сообщ.
#5951
,
|
|
|
|
Цитата MyNameIsIgor @ Есть, например, мьютексы. Тогда вместо создания переменных будет lock() и unlock() в defer. Так блин, в этом же и есть преимущество RAII и как раз мьютексы и приводил в пример D_KEY: lock() в конструкторе, unlock() в деструкторе и используем ![]() ![]() { Mutex m; ... } или не? Это условно, он там более подробный пример приводил. Добавлено Цитата MyNameIsIgor @ Dunno, C++/CLI как-то обошёлся... Потому что это C++ =) Я что-то читал по этому поводу про особенности C++/CLI и его взаимодействие с .NET, но сейчас не вспомню. |
|
Сообщ.
#5952
,
|
|
|
|
Цитата korvin @ или не? Или не Есть просто locker, который делает lock в конструкторе и unlock в деструкторе. Он, кстати, шаблонный и может работать с любым типом с такими методами.А если так, как у вас, то мьютекс будет залочен на протяжении всей его жизни. Добавлено Цитата Adil @ А это пришлось доказывать? O_o Ага Нам так и не поверили |
|
Сообщ.
#5953
,
|
|
|
|
Цитата MyNameIsIgor @ Ну, ok, а если GC так и не доберётся до этого объекта? База так и останется незакрытой? Цитата korvin @ Но ведь это освобождение может и не быть вызвано, как мне тут D_KEY подсказал, что тогда? http://msdn.microsoft.com/ru-ru/library/system.object.finalize.aspx Цитата Во время завершения работы домена приложения Finalize вызывается автоматически для объектов, которые не исключены из финализации, даже для тех, которые остаются доступными. Т.е. при закрытии приложения/выгрузке сборки оно таки будет вызвано. |
|
Сообщ.
#5954
,
|
|
|
|
Цитата korvin @ Цитата MyNameIsIgor @ Это важно в контексте того обсуждения, где доказывалось, что finally - костыль ![]() В C++ может быть и костыль, но в языках с GC без него никак. Как это? RAII успешно справляется. Я же уже неоднократно писал об этом. Питоновские менеджеры контекста, шарповые using'и, новый явовский "try с ресурсами". И зачем в таком случае finally? |
|
Сообщ.
#5955
,
|
|
|
|
Т.е. получается, что реальный практический выхлоп финализаторов - один раз поюзать для некритичной базы? А что тогда они в языке делают? Маскируют ошибки работы с IDisposable?
|