Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.137.220.120] |
|
Страницы: (15) « Первая ... 10 11 [12] 13 14 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#166
,
|
|
|
Это вообще вопрос уровня API. При работе с ресурсами хочет пользователь знать или не очень, а придется. А тот кому не надо, использует API уровня Чудо.сотворись(). |
Сообщ.
#167
,
|
|
|
Цитата wind @ Это вообще вопрос уровня API. При работе с ресурсами хочет пользователь знать или не очень, а придется А зачем? В C++ это вполне может быть делом класса, клиенту это знать не нужно. |
Сообщ.
#168
,
|
|
|
Цитата D_KEY @ В C++ это вполне может быть делом класса, клиенту это знать не нужно. ну то есть когда я пишу пул соединений или пул потоков, то мне не интересно когда и как они закрываются? |
Сообщ.
#169
,
|
|
|
Цитата wind @ ну то есть когда я пишу пул соединений или пул потоков, то мне не интересно когда и как они закрываются? Взял из пула, вернул в пул(автоматически, через подсчет ссылок), что тебе ещё нужно знать? |
Сообщ.
#170
,
|
|
|
Цитата D_KEY @ Взял из пула, вернул в пул Я говорил "пишу", а не "использую". Если я использую класс, представляющий ресурс, я принципиально не могу не знать, что его нужно освобождать. Здорово, если для этого не нужно много телодвижений. Добавлено Цитата D_KEY @ Взял из пула, вернул в пул Хотя тут та же самая ситуация. Я должен точно знать, когда оно возвращается в пул, что я для этого должен сделать, не могу не знать. |
Сообщ.
#171
,
|
|
|
Цитата wind @ Хотя тут та же самая ситуация. Я должен точно знать, когда оно возвращается в пул, что я для этого должен сделать, не могу не знать. Да легко можно не знать. На C++ void foo() { auto connection = pool.get(); connection.exec("delete from idiots"); } Что там в деструкторе connection происходит - не моё дело. |
Сообщ.
#172
,
|
|
|
Цитата MyNameIsIgor @ Да легко можно не знать. Нельзя не знать контракта класса, который ты используешь. А приведенный тобой пример как раз ярко иллюстрирует тот факт, что метод принадлежит вовсе не классу, представляющему ресурс, и в этом случае тебе действительно не нужно знать, каким образом и с какими ресурсами он связан. |
Сообщ.
#173
,
|
|
|
Цитата wind @ Нельзя не знать контракта класса, который ты используешь. А приведенный тобой пример как раз ярко иллюстрирует тот факт, что метод принадлежит вовсе не классу, представляющему ресурс, и в этом случае тебе действительно не нужно знать, каким образом и с какими ресурсами он связан. При чём тут контракт класса? Допустим, у нас имеется некоторый класс-хранилище (Cache) объектов в памяти и такой клиентский код: void foo() { Cache c; // do many actions with cached objects } Теперь мы хотим, чтобы кэш куда-то сохранялся в промежутке между вызовами foo. Мы дописываем соответствующие действия сохранения и восстановления в деструктор и конструктор Cache соответственно и оно работает без изменения кода foo. И foo вообще не нужно знать, как внутри устроен объект класса Cache, сохраняет он что-то куда-то (в более постоянное место в памяти, БД, файлы, в т.ч. и сетевые) или нет. Абстракция, ООП. В случае с языком с GC, нам нужно явно вызывать какой-нибудь метод Cache::close(), которого могло не быть в изначальном интерфейсе класса Cache, и соответственно не быть его вызова в foo, ведь в начале предполагалось, что Cache хранит свои объекты просто в (своей) памяти, которая становится не нужна после выхода из foo, а следовательно и нечего о ней заботится, GC почистит. А вот транзакцию / сетевое соединение он так не закроет сам. |
Сообщ.
#174
,
|
|
|
Цитата korvin @ Теперь мы хотим, чтобы кэш куда-то сохранялся в промежутке между вызовами foo. Мы дописываем соответствующие действия сохранения и восстановления в деструктор и конструктор Cache соответственно и оно работает без изменения кода foo. И не работает, если объект поселили в статическую переменную и не разрушают никогда. Да, можно и шарики себе, в принципе, отстрелить, но такие экстремальные отклонения не рассматриваются. Ты, скорее всего не будешь оставлять "висящие" ресурсы в коде, который ты понятия не имеешь как используют и будешь расширять класс, о котором знают - его инстанс в обязательном порядке надо грохнуть/закрыть после использования. |
Сообщ.
#175
,
|
|
|
Цитата wind @ И не работает, если объект поселили в статическую переменную и не разрушают никогда Так и не предполагалось, что будет работать. Написано же Цитата korvin @ Теперь мы хотим, чтобы кэш куда-то сохранялся в промежутке между вызовами foo. А если вы сами сделали переменную неразрушаемой, то и смысла нет сохранять её состояние. А вот о чём мы тут говорим: в Java/C#/Python и подобном при таком изменении Cache пришлось бы менять код foo для использования конструкций try-with-resource/using/with и подобное. Добавлено Цитата wind @ знают - его инстанс в обязательном порядке надо грохнуть/закрыть после использования Вы не улавливаете суть. Дело в том, что в C++ все экземпляры надо "грохнуть/закрыть после использования". В языках же со сборкой мусора появляется двойственность: объекты, которые потребляют только ресурс "память", грохаются автоматически; а объекты, использующие какие-то ещё ресурсы, надо грохать руками. |
Сообщ.
#176
,
|
|
|
Цитата wind @ Если я использую класс, представляющий ресурс, я принципиально не могу не знать, что его нужно освобождать. Почему? A a = ...; a это ресурс или нет? Если нет, то что изменится, если a станет ресурсом? |
Сообщ.
#177
,
|
|
|
Цитата wind @ 1) И не работает, если объект поселили в статическую переменную и не разрушают никогда. 2) Да, можно и шарики себе, в принципе, отстрелить, но такие экстремальные отклонения не рассматриваются. 3) Ты, скорее всего не будешь оставлять "висящие" ресурсы в коде 4) который ты понятия не имеешь как используют и будешь расширять класс, о котором знают 5) его инстанс в обязательном порядке надо грохнуть/закрыть после использования. 1) А если бабушке пришить... Ну ты понял. 2) Так никто и не рассматривает, приведённый мной пример вполне банален, типичен, «мейнстримен» для C++, никаких отклонений, тем более экстремальных, а ситуация вполне типична для любого ЯП. 3) В примере нет никаких «висящих» ресурсов, что бы это не значило. 4) Я имею право расширять/модифицировать класс как угодно, если это не нарушает его инвариантов (как раз в моём примере никакого нарушения нет), а в общем случае — не меняет его интерфейс. Ибо знают только интерфейс. В этом суть ООП, в знании только интерфейса и полагаться только на интерфейс. 5) Он и так грохается обязательно. Автоматически. Правило симметрии вполне работает: конструктор — захват, деструктор — освобождение. Добавлено Цитата MyNameIsIgor @ В языках же со сборкой мусора появляется двойственность: объекты, которые потребляют только ресурс "память", грохаются автоматически; а объекты, использующие какие-то ещё ресурсы, надо грохать руками. Это компромисс: «объекты, использующие только память» почти всегда количественно преобладают над остальными ресурсами, при чём, обычно, существенно. |
Сообщ.
#178
,
|
|
|
Цитата D_KEY @ a это ресурс или нет? Если нет, то что изменится, если a станет ресурсом? Я должен буду знать, что его нужно как-нибудь побыстрее освободить, капитан. |
Сообщ.
#179
,
|
|
|
Цитата wind @ Цитата D_KEY @ a это ресурс или нет? Если нет, то что изменится, если a станет ресурсом? Я должен буду знать, что его нужно как-нибудь побыстрее освободить, капитан. Зачем? Что значит побыстрее? А обычные объекты ты держишь подольше? Зачем? |
Сообщ.
#180
,
|
|
|
Цитата D_KEY @ Зачем? Что значит побыстрее? А обычные объекты ты держишь подольше? Зачем? Затем чтобы не отковыривать проблемы через месяцы/годы после сдачи проекта. Ты наверняка читал или слушал, например, общие рекомендации (за авторством любого опытного специалиста) при работе с транзакциями в СУБД. Вот воспроизведи про себя. |