Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
1

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

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

Author24 — интернет-сервис помощи студентам
Здорова!
Тут вообщем новую концепцию ООП вычитал "получение ресурса есть инициализация"
Вообщем считается когда используешь исключения, то обязательно нужно соблюдать эту концепцию?
И еще считается, что этот способ очень хороший для работы с умными указателями, но как его можно применить к умным указателям?
Класс умный указатель этож как бы оболочка он токо ссылки содержит, какой там может быть ресурс, какое там освобождение, если он и так ресурсов не содержит????
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.04.2013, 11:21
Ответы с готовыми решениями:

Получение ресурса по id
Есть int массив, котрый заполнен idшниками аудио-ресурсов. Нужно как-то в SoundPool передать по...

Получение строки из ресурса
Помогите, пожалуйста. У меня в файле ресурса есть код для строки и для меню:#define Str 2...

Получение ресурса string в классах
Доброе утро товарищи. Понадобилось получение строк из классов не содержащих context или...

Упаковка ресурса в артефакт и получение пути
Доброго времени суток вам. Сразу надо сказать, что работаю в Intellij IDEA. Есть такая...

Получение (чтение) html файла ресурса в проекте MFC
Здравствуйте! Пишу приложение на с++ для windows. В приложении хочу использовать html шаблон,...

29
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
14.04.2013, 11:23 2
Ресурс — владение указателем. Владение — это обязанность вызвать деструктор объекта, на который указывает этот указатель.
1
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
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 обязательно? хз. как делать.
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
14.04.2013, 11:39 4
А вот именно это и есть понятие владения.

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

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

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

Да и вообще скорее всего ссылки это не ресурс, ресурс это память.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
14.04.2013, 12:21 6
Ресурсы - это не только память.
Если вы открыли файл, вам нужно его закрыть.
Если вы захватили мьютекс, вам нужно будет его освободить.
Если перед началом работы с каким-то объектом нужно его залочить, увеличить счетчик пользователей, вызвать еще-что-нибудь специфической, а по завершении - разлочить, уменьшить или еще что-то - то тут тоже это все лучше делать специальными объектами, которые в конструкторе выполняют "захват", а в деструкторе - "освобождение".
1
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
14.04.2013, 12:34  [ТС] 7
DU, Ну правильно будет скорее всего в классе в то в котором захвачен ресурс в нем и освобождать его, в любом случае деструктор объекта раньше времени не вызовется пока этот объект используется. Да если этот объект будет использоваться в каком нибудь левом классе как бы указателем на этот объект это будет тоже считаться, что объект используется. Сразу трудно понять эту фигню.
0
13 / 13 / 2
Регистрация: 13.09.2013
Сообщений: 113
26.06.2014, 19:34 8
Хотелось бы поднять тему и задать такой вопрос : RAII - это не панацея ведь ?
Например есть класс,задача которого владеть памятью. В его конструкторе есть строчка int* p = new int[x];После того как выполнилась эта строчка генерируется исключение. Получается, что деструктор класса не будет вызван,память,которая была выделена - не будет возвращена. Т.е. если объект не удалось полностью сконструировать,а один и ресурсов будет уже захвачен (в нашем случае память) , то на корректное освобождение этого ресурса надеется не стоит ?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
26.06.2014, 20:33 9
Цитата Сообщение от TheChosenOne Посмотреть сообщение
то на корректное освобождение этого ресурса надеется не стоит ?
конечно нет. И это касается не только конструкторов классов.
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
26.06.2014, 20:36 10
TheChosenOne, мораль - пишите такие конструкторы, которые не кидают исключений после захвата ресурса.
0
13 / 13 / 2
Регистрация: 13.09.2013
Сообщений: 113
26.06.2014, 20:51 11
Croessmah, ну сам принцип RAII наталкивает меня на то,что если в конструкторе будет брошено исключение,то вся стратегия полетит...ммм... в космос
0x10, а как мне написать класс,который будет захватывать память и при этом будет корректно ее освобождать в случае если не удалось захватить весь ее объем( например мне нужна память для одного числа int и одного числа double ) ? Что делать если мне удалось получить память для int,а вот для double не хватило ?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
26.06.2014, 21:08 12
Цитата Сообщение от TheChosenOne Посмотреть сообщение
Что делать если мне удалось получить память для int,а вот для double не хватило ?
умные указатели. Всё уже давно реализованно
0
3257 / 2059 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
26.06.2014, 21:12 13
Цитата Сообщение от TheChosenOne Посмотреть сообщение
а как мне написать класс,который будет захватывать память и при этом будет корректно ее освобождать в случае если не удалось захватить весь ее объем
Каждая аллокация памяти - захват отдельного ресурса. Про умные указатели сказали выше.
0
18841 / 9840 / 2408
Регистрация: 30.01.2014
Сообщений: 17,283
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_;
};
2
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
26.06.2014, 23:11 15
Цитата Сообщение от DrOffset Посмотреть сообщение
Т.е. если используешь эту идиому - использовать ее нужно везде.
думаю, имеется ввиду что если в конструкторе a_ вылетит исключение, но такие классы проектируются так, чтобы этого не случилось.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
27.06.2014, 10:33 16
Цитата Сообщение от TheChosenOne Посмотреть сообщение
В его конструкторе есть строчка int* p = new int[x];После того как выполнилась эта строчка генерируется исключение.
Следовательно надо сделать так, чтобы за выделение памяти отвечал отдельный объект, т.е. вместо int* заведите например std::vector<int>.
1
13 / 13 / 2
Регистрация: 13.09.2013
Сообщений: 113
28.06.2014, 00:41 17
Tulosba, да,я уже разобрался,спасибо

Добавлено через 1 час 16 минут
А вызов деструкторов для уже созданных объектов гарантирует реализация С++ или этот вызов как-то связан с областью видимости?Т.е. что вызывает деструктор ?

Добавлено через 25 минут
Интересно вот что : Если было брошено исключение,но нет его обработчика,объект конструируется,но не полностью... И существует в таком виде до конца области видимости... Т.е. если объект не удалось создать полностью ,то под-объекты которые были созданы продолжают существовать (вместе с не до конца созданным объектом). Но если вдруг есть обработчик ,тогда все норм. Ощущение что механизм раскрутки стека работает только когда есть обработчик... И подобъекты уничтожаются только когда находится обработчик,а не по мере раскрутки стека...

Добавлено через 30 минут
Упс,ошибочка вышла,terminate() вызывается,с последним разобрался...
0
18841 / 9840 / 2408
Регистрация: 30.01.2014
Сообщений: 17,283
28.06.2014, 00:58 18
Цитата Сообщение от TheChosenOne Посмотреть сообщение
Ощущение что механизм раскрутки стека работает только когда есть обработчик
Нет. Деструкторы вызываются при выходе из области видимости. Выход любым легальным способом, в том числе через исключение.
0
13 / 13 / 2
Регистрация: 13.09.2013
Сообщений: 113
28.06.2014, 01:40 19
DrOffset, Из какой области видимости выходят подобъекты ? Конструтора?Но они не являются локальными по отношению к конструктору. try блока ? Ну тогда должен вызываться деструктор всего объекта,а этого не может быть т.к. объект не был создан.

Добавлено через 9 минут
15.2/2
An object that is partially constructed or partially destroyed will have destructors executed for all of its
fully constructed subobjects, that is, for subobjects for which the constructor has completed execution and
the destructor has not yet begun execution
Все что нашел в стандарте... Ничего про область видимости...

Добавлено через 12 минут
на SOF мне ответили что сам конструктор недоконструированного объекта вызывает деструкторы подобъектов..Может кто-нибудь скажет что-то еще на этот счет ?
0
18841 / 9840 / 2408
Регистрация: 30.01.2014
Сообщений: 17,283
28.06.2014, 02:09 20
Цитата Сообщение от TheChosenOne Посмотреть сообщение
try блока ? Ну тогда должен вызываться деструктор всего объекта,а этого не может быть т.к. объект не был создан.
Не try блока, а в том числе try блока. Той области видимости, где была попытка создания объекта (try-блок, функция, scope и т.п.). Уже созданные подобъекты принадлежат этой же области видимости, что и главный объект. Вот такой же код не вызывает вопросов?
C++
1
2
3
4
5
6
7
8
9
10
11
12
void foo()
{
    A a;
    B b; 
 
// throw и выход из области видимости    
    throw std::logic_error("");
         // вызов ~B()
         // вызов ~A()
    
    C c; // ~C() не вызывается 
}
Ситуация c подобъектами эквивалентна вышеописанной, представим что С у нас главный объект, а A и B - подобъекты.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class C
{
public:
    C() : a()
        , b() 
    {
        throw std::logic_error("");
    } 
 
private:
    A a;
    B b; 
}
 
// порядок создания тот же
void foo()
{
//  A a;
//  B b;
    C c; // throw и выход из области видимости 
         // вызов ~B()
         // вызов ~A()
         // ~C() не вызывается 
}
0
28.06.2014, 02:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.06.2014, 02:09
Помогаю со студенческими работами здесь

Получение Utilization отдельного ресурса (Unit) конкретного ResourcePool
Добрый день! Подскажите, пожалуйста, как вытащить утилизацию отдельного ресурса блока ResourcePool?

Найдите все такие значения К, при которых есть выигрышная стратегия
Задание 5. Для игры, которая описана в п задании 4, при N — 32 найдите все такие значения К, при...

Укажите такое значение S, при котором у Вани есть выигрышная стратегия
Два иг*ро*ка, Петя и Ваня, иг*ра*ют в сле*ду*ю*щую игру. Перед иг*ро*ка*ми лежит куча кам*ней....

Получение Модели DOM (Web ресурса), загруженной JAVA приложением на компе
Всем здравствуйте! Описание проблемы: Есть информационная система работа с которой...

Найти наибольшее значение К, при котором есть выигрышная стратегия, позволяющая выиграть своим первым ходом
Задание 6. Для игры, которая описана в задании 4, при N = 20 найдите наибольшее значение К, при...

Есть AVI в виде ресурса, как его показать в форме?
Есть AVI в виде ресурса, кто знает как его показать в форме? Или все-же лучше не захламлять...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru