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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
#1

Стратегия "получение ресурса есть инициализация" - C++

14.04.2013, 11:21. Просмотров 1397. Ответов 29
Метки нет (Все метки)

Здорова!
Тут вообщем новую концепцию ООП вычитал "получение ресурса есть инициализация"
Вообщем считается когда используешь исключения, то обязательно нужно соблюдать эту концепцию?
И еще считается, что этот способ очень хороший для работы с умными указателями, но как его можно применить к умным указателям?
Класс умный указатель этож как бы оболочка он токо ссылки содержит, какой там может быть ресурс, какое там освобождение, если он и так ресурсов не содержит????
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.04.2013, 11:21     Стратегия "получение ресурса есть инициализация"
Посмотрите здесь:
Error C2440: инициализация: невозможно преобразовать "void *" в "listnode *". подскажите, что можно сделать? C++
Warning C4244: инициализация: преобразование "__int64" в "int", возможна потеря данных C++
C++ Дана строка, в котором есть слово "да" или слово "нет". Если в нем есть слово "нет", то удалить его
C++ трудности с пониманием синтаксиса на примере реализации паттерна "стратегия"
C++ Что делать с ошибкой: C2440: инициализация: невозможно преобразовать "int **" в "int *"
C++ Модель распределения памяти разделами переменного размера с общей очередью, стратегия "наименее подходящий"
Как сделать, так чтобы i и j можно было вводить самому "i" И "j" в цикле, есть программа C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
14.04.2013, 11:23     Стратегия "получение ресурса есть инициализация" #2
Ресурс — владение указателем. Владение — это обязанность вызвать деструктор объекта, на который указывает этот указатель.
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
14.04.2013, 11:27  [ТС]     Стратегия "получение ресурса есть инициализация" #3
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Ресурс — владение указателем. Владение — это обязанность вызвать деструктор объекта, на который указывает этот указатель.
А от если у меня есть такой класс который просто тупо как бы ссылки содержит, то что я должен в деструкторе вызвать?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Ptr
{
    int* p;//ykazatel6 na tekychii element
    int* array;//ykazatel6 na macciv
    int size;//razmer macciva
    
public:
    class Run_time_error {};
    //konctryktor preobrazovani9
    Ptr_to_T(int*p, int* v, int s)//priv9zka k maccivy v razmera s; nach. znachenie p
    :p(p),array(v),size(s){}
    
    ~Ptr_to_T(){};
};
Я ж оператор new здесь не вызываю вроде, ток что мне тогда освобождать?
Я вообще считаю если new вызывается тогда токо можно что то освободить вызвал delete. А в случае с классом выше как быть? Или мне нужно вызвать new обязательно? хз. как делать.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
14.04.2013, 11:39     Стратегия "получение ресурса есть инициализация" #4
А вот именно это и есть понятие владения.

Класс Ptr обладает ссылками на объекты, но не обязан их удалять. То есть он не контролирует их время жизни, не владеет ими. Он просто получил указатели на какие-то объекты, созданные ранее.

Соответственно, возникает проблема: эти объекты нельзя удалить, пока они нужны Ptr. Для её решения можно поступить двумя путями: или передавать Ptr владение над этими объектами, или разделить владение между несколькими объектами. Для первого случая есть std::unique_ptr — при его передаче предыдущий владелец теряет ссылки на эти объекты, а вместе с ними и обязательство удалять объекты, тогда как Ptr всё это получает. Для второго случая есть std::shared_ptr — тогда оба объекта (и предыдущий владелец, и этот Ptr) совместно владеют одним объектом, удалять этот объект будет тот, кто останется последним.
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
14.04.2013, 11:48  [ТС]     Стратегия "получение ресурса есть инициализация" #5
Не знаю даже как это от если у меня массив будет int v[200], То я просто инициализирую Ptr
Ptr b(v[0],v,200); Я ж наверно не смогу в деструкторе удалить этот объект никак, да мне даже вызывать его смысла нету (да и не зачем), ведь там же храниться будет не копия ресурсов, а ссылки на эти ресурсы, значит смысл удалять (освобождать)? В данном случае наверно нету смысла, если б копия, а это наверно пришлось бы хапать новую область памяти и туда просто перекопировать значение тогда да нужно было б высвободить память. Ну правильно ж? Скажи, что мне деструктор в классе можно и не определять?

Да вообще проще считать, что деструктор это как очиститель, то есть удаляет данные токо те которые как бы загватил класс, к левым данным напимер ссылки смысла нету лезть. Так будет впринципе правильно.

Да и вообще скорее всего ссылки это не ресурс, ресурс это память.
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
14.04.2013, 12:21     Стратегия "получение ресурса есть инициализация" #6
Ресурсы - это не только память.
Если вы открыли файл, вам нужно его закрыть.
Если вы захватили мьютекс, вам нужно будет его освободить.
Если перед началом работы с каким-то объектом нужно его залочить, увеличить счетчик пользователей, вызвать еще-что-нибудь специфической, а по завершении - разлочить, уменьшить или еще что-то - то тут тоже это все лучше делать специальными объектами, которые в конструкторе выполняют "захват", а в деструкторе - "освобождение".
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
14.04.2013, 12:34  [ТС]     Стратегия "получение ресурса есть инициализация" #7
DU, Ну правильно будет скорее всего в классе в то в котором захвачен ресурс в нем и освобождать его, в любом случае деструктор объекта раньше времени не вызовется пока этот объект используется. Да если этот объект будет использоваться в каком нибудь левом классе как бы указателем на этот объект это будет тоже считаться, что объект используется. Сразу трудно понять эту фигню.
TheChosenOne
13 / 13 / 1
Регистрация: 13.09.2013
Сообщений: 113
26.06.2014, 19:34     Стратегия "получение ресурса есть инициализация" #8
Хотелось бы поднять тему и задать такой вопрос : RAII - это не панацея ведь ?
Например есть класс,задача которого владеть памятью. В его конструкторе есть строчка int* p = new int[x];После того как выполнилась эта строчка генерируется исключение. Получается, что деструктор класса не будет вызван,память,которая была выделена - не будет возвращена. Т.е. если объект не удалось полностью сконструировать,а один и ресурсов будет уже захвачен (в нашем случае память) , то на корректное освобождение этого ресурса надеется не стоит ?
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
26.06.2014, 20:33     Стратегия "получение ресурса есть инициализация" #9
Цитата Сообщение от TheChosenOne Посмотреть сообщение
то на корректное освобождение этого ресурса надеется не стоит ?
конечно нет. И это касается не только конструкторов классов.
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,012
26.06.2014, 20:36     Стратегия "получение ресурса есть инициализация" #10
TheChosenOne, мораль - пишите такие конструкторы, которые не кидают исключений после захвата ресурса.
TheChosenOne
13 / 13 / 1
Регистрация: 13.09.2013
Сообщений: 113
26.06.2014, 20:51     Стратегия "получение ресурса есть инициализация" #11
Croessmah, ну сам принцип RAII наталкивает меня на то,что если в конструкторе будет брошено исключение,то вся стратегия полетит...ммм... в космос
0x10, а как мне написать класс,который будет захватывать память и при этом будет корректно ее освобождать в случае если не удалось захватить весь ее объем( например мне нужна память для одного числа int и одного числа double ) ? Что делать если мне удалось получить память для int,а вот для double не хватило ?
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
26.06.2014, 21:08     Стратегия "получение ресурса есть инициализация" #12
Цитата Сообщение от TheChosenOne Посмотреть сообщение
Что делать если мне удалось получить память для int,а вот для double не хватило ?
умные указатели. Всё уже давно реализованно
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,012
26.06.2014, 21:12     Стратегия "получение ресурса есть инициализация" #13
Цитата Сообщение от TheChosenOne Посмотреть сообщение
а как мне написать класс,который будет захватывать память и при этом будет корректно ее освобождать в случае если не удалось захватить весь ее объем
Каждая аллокация памяти - захват отдельного ресурса. Про умные указатели сказали выше.
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
26.06.2014, 23:07     Стратегия "получение ресурса есть инициализация" #14
Цитата Сообщение от TheChosenOne Посмотреть сообщение
то вся стратегия полетит...ммм... в космос
Ничего никуда не летит. Просто правильное применение предполагает последовательность. Т.е. если используешь эту идиому - использовать ее нужно везде.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class A
{
public:
    A() 
        : a_(new int[2]) // RAII
    {
         throw std::logic_error("catch this"); // исключение, 
                                               // но деструктор уже созданных объектов гарантированно 
                                               // вызовется при этом. В итоге, благодаря RAII, a_ освободит память.
    }
private:
    std::unique_ptr<int[]> a_;
};
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.06.2014, 23:11     Стратегия "получение ресурса есть инициализация"
Еще ссылки по теме:
Для массива из 10 чисел проверить, есть ли в нем два одинаковых числа и напечатать "да" или "нет" C++
C++ Заданный словарь слов. Найти в нем слова-палиндромы, то есть такие, которые одинаково читаются слева направо и наоборот, например, "АННА", "ШАЛАШ"
Если в строке есть хоть один ноль - вывести в файл output.txt "YES", иначе вывести "NO"; C++
Для агрегатного объекта требуется инициализация с использованием "{.}" C++
C++ Инициализация массива: ошибка "array must be initialized with a brace-enclosed initializer"

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

Или воспользуйтесь поиском по форуму:
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
26.06.2014, 23:11     Стратегия "получение ресурса есть инициализация" #15
Цитата Сообщение от DrOffset Посмотреть сообщение
Т.е. если используешь эту идиому - использовать ее нужно везде.
думаю, имеется ввиду что если в конструкторе a_ вылетит исключение, но такие классы проектируются так, чтобы этого не случилось.
Yandex
Объявления
26.06.2014, 23:11     Стратегия "получение ресурса есть инициализация"
Ответ Создать тему
Опции темы

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