Здравствуйте, Mystic Artifact, Вы писали:
EP>>Это больше 99% случаев. MA>>>Я о полях вида ptr<T> разного толка. EP>>А это соответственно меньше 1%. MA>Ну ты просто не можешь аггрегировать объекты которыми не владеешь.
Обычно когда внутри класса появляется файл, в который этот класс пишет — это агрегирование.
MA>Статистики у меня нет. Если ты получил смарт-поинтер — то с ним и живёшь.
Ну и ок, пришёл смарт-поинтер, ресурс всё равно автоматом освободится. Но классы использующие (напрямую или косвенно) этот класс со смарт-поинтером внутри, менять не нужно, в отличии от.
EP>>>>В большинстве случаев они не нужны — ну то есть если взять места в программе где создаются объекты, и посчитать в скольких случаях нужны какие-либо смарт-поинтеры — то окажется что это доли процента от общего числа, а в подавляющем большинстве случаев происходит так как в Widget выше MA>>> Ну, я вижу скорее обратное: почти всё завязано на какие-нибудь обертки. это от объектов-прокси IPC, параметры-колбэки и т.п. EP>>Ну вот например std::vector или std::function — ты к чему относишь? К смарт-поинтерам? MA> Не понимаю к чему вопрос.
К тому что например параметры-колбэки это обычно std::function или подобное, внутри указатели с динамической аллокацией (при выходе за рамки по размеру), я думал может ты их причисляешь к смарт-поинтерам, поэтому и считаешь что в программах они используются везде.
MA> В C#, в отлиии от C++ — в ручную необходимо управлять только непосредственно ресурсами, и управление ими по большому счету сосредотачивается в библиотечном коде.
Ну вот основной поинт как раз в том, что не получится полностью вынести управление в библиотечный код, абстракция сразу протекает в пользовательских код — ибо если какой-то класс стал IDisposable (тот самый FileStream в качестве поля), даже на самом низком уровне, то всё что его использует напрямую или косвенно, транзитивно нужно менять, включая пользовательский код.
MA>В C++ полуручник всегда рядом в перемешку с голыми указателями.
В управляемых языках полного автомата нет, к примеру от утечек памяти GC не защищает.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Тогда приплыли, ибо тогда класс становится IDisopsable и его тоже надо оборачивать в using, но главное что это касается также всех кто напрямую или косвенно содержат объект этого класса. Но, это проблема только в языках без нормального scope-based lifetime (using'и, try-with-resources, with, как видишь, проблему не решают)
Можно использовать шаблон Lifetime, он чистит объекты более грамотно, чем юзинг
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>Что-то почти всегда минусов от исключений больше чем плюсов ... VYR>Можно вобще не обрабатывать — закроется с ошибкой (типо почти нормально?) — но какой тогда смысл в их использовании??? VYR>Может подскажите как меньшими силами обходит похожие грабли ???
Переходи на cl там есть система сигналов и перезапусков, про racket не уверен,
есть попытки реализовать это на системах с исключениями: на кложе(джава) и на C#(.net).
Описание этого способа обработки ошибок из книги практический лисп очень впечатлило.
Любая стратегия на любом уровне без раскрутки стэка.
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>Что-то почти всегда минусов от исключений больше чем плюсов ... VYR>например такой пример: VYR>
VYR> class Program
VYR> {
VYR> static void Fx()
VYR> {
VYR> FileStream f = new FileStream("D:\\1.txt",FileMode.Append);
VYR> f.Write(UnicodeEncoding.UTF8.GetBytes("zzz"));
VYR> throw new Exception("test");//предположим вызвалось в процессе работы исключение!!!
VYR> f.Close();
VYR> }
VYR> static void Main(string[] args)
VYR> {
VYR> try {
VYR> Fx();
VYR> }
VYR> catch (Exception e)
VYR> {
VYR> Console.WriteLine("zzz");
VYR> }
VYR> Console.WriteLine("Hello World!");
VYR> }
VYR> }
VYR>
И еще, прежде чем двигаться дальше, поясни что делает этот код?
Не уверен, но либо это ГК, либо все это высосано из пальца.
Успешно записали в файл, затем бахнули исключение.
Писать такое код можно поручить генератору случайных чисел.
Даже джун будет в этом случае открывать файл через юзинг.
Ведь скоуп локальный.
Давайте будем реалистами!
допустим обрабатываем востанавливаемые исключения и номера строк и функцию нашли ...
теперь что сообщить пользователю если эта функция используется 10 раз и многое зависит от её параметров (пользователь номера строк не поймёт)
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>ещё один камень в огород...
VYR>допустим обрабатываем востанавливаемые исключения и номера строк и функцию нашли ... VYR>теперь что сообщить пользователю если эта функция используется 10 раз и многое зависит от её параметров (пользователь номера строк не поймёт)
Кроме сообщения об ошибке может потребоваться дать пользователю возможность:
1. завершить программу
2. исправить данные и повторить попытку обработать данные
3. пропустить данные содержащие ошибку
4. ...
С исключениями у нас одна возможность это сделать — жестко закодировать.
В системе перезапусков можно гибко настроить различное поведение.
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>ещё один камень в огород...
VYR>допустим обрабатываем востанавливаемые исключения и номера строк и функцию нашли ... VYR>теперь что сообщить пользователю если эта функция используется 10 раз и многое зависит от её параметров (пользователь номера строк не поймёт)
Вот с учетом этих параметров и формировать ответ пользователю.
Приведите кусок кода, который вызывает затруднения. Так, видимо, будет проще разобраться.
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>Что-то почти всегда минусов от исключений больше чем плюсов ...
Исключения, как и любой другой инструмент, надо уметь применять и понимать, когда их использование будет лучшим решением.
В приведённом примере:
Исключения можно ловить в этой же функции, освобождать ресурс и возвращать код ошибки. Можно, после освобождения ресурса пробрасывать исключение выше, если нужно ловить его в вызывающей функции.
В Java можно использовать AutoClosable и try-with-resources. В C++ — умный указатель или создание переменной на стеке, а не в куче, и освобождать ресурсы в деструкторе. В других языках тоже существуют механизмы для решения проблемы.
Здравствуйте, varenikAA, Вы писали:
AA>Можно использовать шаблон Lifetime, он чистит объекты более грамотно, чем юзинг
Это Region/Arena, вид сбоку (для ресурсов): https://en.wikipedia.org/wiki/Region-based_memory_management
Со своими минусами (например избыточным временем жизни ресурсов). По сути является тем же scope'ом, только укрупнённым — собственно там в примере Lifetime сам создаётся using'ом, поэтому говорить что он чистит объекты "более грамотно" некорректно.
И опять таки, проблема с транзитивностью никуда не делась — если Lifetime является полем объекта и привязан к времени его жизни, то все прямые и непрямые пользователи этого объекта сами становятся IDisposable.
AA>https://github.com/sidristij/dotnetbook/tree/master/book/ru (Лекция на ютубе https://youtu.be/F5oOYKTFpcQ )
Там WhenAll это вообще подсчёт ссылок, только реализация квадратичная
VYR>>для состояний внутри класса (даже если не конечным автоматом) — это просто кашмар как неудобно... M>Потому исключение и называется исключением. Не предусмотренная алгоритмом внештатная ситуация.
А вот если сравнить все плюсы и минусы обработки востанавливаемых ошибок, на на примере выбора файла,
что лучше — чтобы API исключения давали или флаги возвращали???
С флагами всё логично даже цикл можно написать с отменой...
А вот с исключениями одни сплошные {{ }} на каждой обрабатываемой функции...
Помоему исключения только для невостанавливаемых ошибок хороши и только для тех которые недотестировали...
(чтобы не ложилось всё приложение с несохранёнными данными)
Здравствуйте, vvv848165@ya.ru, Вы писали:
VYR>Помоему исключения только для невостанавливаемых ошибок хороши и только для тех которые недотестировали... VYR>(чтобы не ложилось всё приложение с несохранёнными данными)
Ну когда весь код утыкан констукциями
if (result == RESULT_OK)
{
...
}
if (result == RESULT_OK)
{
...
}
if (result == RESULT_OK)
{
...
}
или
if (result == RESULT_OK)
{
...
if (result == RESULT_OK)
{
...
if (result == RESULT_OK)
{
...
}
}
}