Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.69
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
#1

Методы init() и dispose() - теория - C++

11.07.2013, 17:16. Просмотров 1756. Ответов 44
Метки нет (Все метки)

Всегда интересовало, зачем существуют эти методы? Допустим, есть некоторый объект класса и в коде видим:
C++
1
2
3
4
5
x = new myClass();
x.init();
...
x.dispose();
delete x;
Одно дело, если бы в эти методы передавались параметры, а другое дело это. Разве не проще было бы весь код init поместить в конструктор, а dispose, соответственно, в деструктор?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.07.2013, 17:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Методы init() и dispose() - теория (C++):

Виртуальные методы(теория) - C++
Здравствуйте уважаемые форумчане! В ходе обучения языку с++ возник вопрос непонимания назначения виртуальных методов. Попытался...

No init for const! - C++
Доброе утро, котаны!:) Вопрос - в джаве есть возможность сделать такую штуку final boolean someBool; someBool = true; То есть...

Lambda init capture by const reference - C++
Всем привет. Почему не получается добиться следующего поведения: auto main() -> int { int ival = 0; () { // Need...

функция вида init( struct ****) - segmentation fault - C++
Прошу помочь, уже всю голову сломал. Дан следующий код struct square { bool is_rect; int is_side; struct square...

Что делает оператор init в данной ситуации (работа с двумерными массивами) - C++
Есть фрагмент кода C++. const int ROWS = 10, COLUMNS = 10; int matrix; init(&matrix); int temp, sum = 0;

Разработать классы для описанных ниже объектов. Включить в класс методы set (…), get (…), show (…). Определить другие методы - C++
Разработать классы для описанных ниже объектов. Включить в класс методы set (…), get (…), show (…). Определить другие методы Abiturient:...

44
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
11.07.2013, 18:33 #16
Avazart, Ошибка при уничтожении происходить не должна, если происходит ошибка при уничтожении - мы должны
1) Обработать исключение, не выпустив его за границы деструктора.
2) Возможно записать что-то в лог/отправить e-mail разработчикам/что-то еще и либо проигнорировать, либо завершить работу приложения.

А на тему метода: смысла в этом довольно мало, в языках типа C#/Python это вполне себе ОК практика, ибо сборка мусора, ибо finally.
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,806
Записей в блоге: 17
11.07.2013, 18:37 #17
К примеру пытался недавно написать обвёрку под конкретную задачу для SQLite, и поначалу не учёл что закрытие БД может возвращать ошибку

SQLite Блокровка/разблокировка

Цитата Сообщение от ForEveR Посмотреть сообщение
1) Обработать исключение, не выпустив его за границы деструктора.
2) Возможно записать что-то в лог/отправить e-mail разработчикам/что-то еще и либо проигнорировать, либо завершить работу приложения.
Хм а как это будет выглядеть ? Добавлять в класс указатель на объект лога ?
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
11.07.2013, 18:42 #18
Avazart, Зависит от стратегии выбранной для логирования и так далее. Примитивно как-то так

C++
1
2
3
4
5
6
7
8
9
10
11
12
~Class()
{
   try
   {
       free_resources();
   }
   catch (const std::exception& e)
   {
       // write and ignore exception
       log::instance().write(e.what());
   }
}
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,806
Записей в блоге: 17
11.07.2013, 18:55 #19
Цитата Сообщение от ForEveR Посмотреть сообщение
либо завершить работу приложения.
Ну валить приложение по моему из-за одного объекта не всегда допустимо.

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
Avazart, Зависит от стратегии выбранной для логирования и так далее. Примитивно как-то так


C++
1
2
3
4
5
6
7
8
9
10
11
12
~Class()
{
 try
 {
 free_resources();
 }
 catch (const std::exception& e)
 {
 // write and ignore exception
 log::instance().write(e.what());
 }
}
Ну связывать классы лога и класса-обвертки тоже на мой взгляд выглядит не ахти...
Ибо логов может быть много они могу меняться в процессе разработки итп, и если разработчику приложения ( не класса-обвертки)
приходится лезть и править каждый раз обвертку - это ой как не хорошо.

Уж лучше стратегия подобная Си с методами Open() / Close() ( с кодами возврата или исключениями не важно )
0
ForEveR
В астрале
Эксперт С++
7978 / 4737 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
11.07.2013, 19:12 #20
Avazart, Каждому свое. Конечно валить приложение не всегда стоит. И не всегда стоит использовать лог. Да и куча еще всяких "не" и нюансов.
0
Tulosba
:)
Эксперт С++
4396 / 3232 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
12.07.2013, 09:53 #21
Цитата Сообщение от nexen Посмотреть сообщение
а разве x = null не вызывает практически сразу сборку мусора?
Время вызова сборщика мусора в общем случае не детерминировано. А иногда важный ресурс нужно освободить как можно раньше (например закрыть файл сразу как закончили в него писать, а не ждать пока сборщик мусора до него доберется и вызовет Finalize()), поэтому и придумали подход с Dispose().
2
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
12.07.2013, 21:33 #22
А ещё init() и dispose() нужны, когда вам надо создать объект в "другом мире" (с помощью конструкторов какой-нибудь динамической библиотеки, или вообще другого процесса). Когда "местные" operator new() и operator delete() не подходят.
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
13.07.2013, 13:00 #23
Цитата Сообщение от ForEveR Посмотреть сообщение
Avazart, Зависит от стратегии выбранной для логирования и так далее. Примитивно как-то так

C++
1
2
3
4
5
6
7
8
9
10
11
12
~Class()
{
   try
   {
       free_resources();
   }
   catch (const std::exception& e)
   {
       // write and ignore exception
       log::instance().write(e.what());
   }
}
Плохой вариант, где гарантии что в Catch блоке не вылетит еще одно исключение?
0
Avazart
Эксперт С++
7213 / 5385 / 286
Регистрация: 10.12.2010
Сообщений: 23,806
Записей в блоге: 17
13.07.2013, 13:02 #24
Цитата Сообщение от Герц Посмотреть сообщение
Плохой вариант, где гарантии что в Catch блоке не вылетит еще одно исключение?
Ну так в try больше ничего другого нет...
1
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
13.07.2013, 13:23 #25
Цитата Сообщение от Герц Посмотреть сообщение
Плохой вариант, где гарантии что в Catch блоке не вылетит еще одно исключение?
Нигде. Если сломалось (локально расположнное) логгирование, то это уже проблемы вышележащего кода, что с этим делать.
2
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6486 / 3130 / 307
Регистрация: 04.12.2011
Сообщений: 8,644
Записей в блоге: 5
13.07.2013, 15:04 #26
В средах с gc применение Dispose() нормальная практика. Интересно, действительно подумать, а как это в С++.)
Поразмыслив пришла мысль, а что если вопрос применения таких методов, - может быть и вопросом времени? Смотрите, стоит только не высказать глупость, как тут же её никто и не опровергнет. То есть налицо потеря времени!
Придётся, высказаться. Предположим есть класс с набором "тяжелых" полей, для которых применяется отложенная (ленивая инициализация). То есть конструктор не проводит их инициализацию, а необходимые вычисления осуществляют методы доступа при первом обращении. Тогда, если есть группа объектов, для которых точно потребуется полная инициализация, а участок кода в которых они задействованы должен выполниться максимально быстро, то можно принудительно инициализировать их в специальном методе, до вхождения в данный блок кода.
Пользуясь той же логикой, Dispose(), - дополнительный метод выполняющий принудительное освобождение, не проверяя занят ли ресурс (если проверка требует времени). Это быстро и... если пользователь применит не там, где нужно, - получит исключение и опомнится. Что касается вопросов типа: - "А что если?!", то всегда можно спросить: - "А вдруг кто-то дважды применит delete?" Последнее, конечно дискуссионный вопрос.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
13.07.2013, 15:15 #27
Цитата Сообщение от IGPIGP Посмотреть сообщение
В средах с gc применение Dispose() нормальная практика. Интересно, действительно подумать, а как это в С++.)
В Си++ есть RAII.
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6486 / 3130 / 307
Регистрация: 04.12.2011
Сообщений: 8,644
Записей в блоге: 5
13.07.2013, 15:48 #28
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
В Си++ есть RAII.
Dispose() можно использовать чтобы побудить gc... RAII помогает автоматически удалять объекты при выходе из видимости. В том числе при применении smart-указателей. Неужели применение Dispose() может побудить систему освободиться от динамического объекта с доступом через такой указатель (ссылок на который уже нет, разумеется) ещё в пределах области?
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
13.07.2013, 17:18 #29
Нет, Dispose (в CLR) — это метод, освобождающий все unmanaged-ресурсы, которыми владеет объект (открытые файлы, разделяемую память и всё такое), чтобы после этого остались только managed-ресурсы, которые подчистит уже GC. Это не подсказка GC: "А ну быстро отдал мне память, занимаемую этим объектом", и объект после вызова этого метода не находится в неопределённом состоянии. Он просто позакрывал всякие хендлы, но в принципе ещё никуда не делся.
2
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6486 / 3130 / 307
Регистрация: 04.12.2011
Сообщений: 8,644
Записей в блоге: 5
13.07.2013, 17:28 #30
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Нет, Dispose (в CLR) — это метод, освобождающий все unmanaged-ресурсы, которыми владеет объект (открытые файлы, разделяемую память и всё такое), чтобы после этого остались только managed-ресурсы, которые подчистит уже GC.
С неуправляемыми ресурсами понятно. Хотя можно их и руками освободить где-то ещё. Пусть есть класс управляемый из управляемого. Я не утверждаю, что Dispose() принуждает gc освободить ресурсы, но как правило, он слушается. По моим наблюдениям.
В С++ это же не ключевое слово. В С тоже. Там Init() использовали для инициализации структур, как стиль. Назвать можно бы как угодно. Вопрос же в том есть ли сейчас этому применение?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.07.2013, 17:28
Привет! Вот еще темы с ответами:

Создать класс Triad (тройка чисел) - определить методы; определить производный класс Date - переопределить методы - C++
Создать класс Triad (тройка чисел); определить методы увеличения полей на 1. Определить производный класс Date с полями: год, месяц и день....

Методы у JInternalFrame: setClosed(true); dispose(); - Java
Проблема следующая: по нажатию на кнопку создается окно JInternalFrame win = new JInternalFrame('New',true,true,true,true);потом в это...

Это правда, что Close() и Clear() методы в .NET классах вызывают Dispose()? - .NET
Всем привет. Подскажите, пожалуйста: 1) Это правда, что Close() и Clear() методы в .NET классах вызывают Dispose()? 2) Блок using()...

Ошибка при загрузке Ubuntu 14.04 LTS: run-init: /sbin/init: Permission denied - Ubuntu Linux
Здравствуйте! На компьютере установлена Uuntu 14.04 LTS (64 bit). После установки cups (для соединения с принтером) система перестала...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Yandex
Объявления
13.07.2013, 17:28
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru