Шаблон для идиомы RAII
От: Basil2 Россия https://starostin.msk.ru
Дата: 28.12.09 15:58
Оценка:
Чисто чтобы не забывать закрывать виндовые хендлы, набросал примитивный шаблон:


template<typename T>
class CallOnScopeLeave
{
   typedef int (__stdcall *func_type)(T); // int & stdcall need for calling Win API
   func_type Func;
   T Param;

public:
   CallOnScopeLeave(func_type func, T par) : Func(func), Param(par) {};
   ~CallOnScopeLeave()
   {
      Func(Param);
   };
};



Используется, понятное дело, так:

HANDLE hFile = CreaterFile(...);
if (hFile == INVALID_HANDLE_VALUE) 
   return;
CallOnScopeLeave<HANDLE>(&CloseHandle, hFile);
// работа с хэндлом...


А вопрос такой. Наверняка эт не я один умный , и такие шаблоны уже существует. Линканите плз какой-нибудь более-менее известный и стандартный. (Без заточки под винду, как у меня, да и вообще хочется посмотреть на "тру" RAII-шаблон )
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re: Шаблон для идиомы RAII
От: denisko http://sdeniskos.blogspot.com/
Дата: 28.12.09 16:04
Оценка: +1
Здравствуйте, Basil2, Вы писали:

B>Чисто чтобы не забывать закрывать виндовые хендлы, набросал примитивный шаблон:


shared_ptr со заданным деструктором?
<Подпись удалена модератором>
Re: Шаблон для идиомы RAII
От: rg45 СССР  
Дата: 28.12.09 16:16
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Чисто чтобы не забывать закрывать виндовые хендлы, набросал примитивный шаблон:


B>
B>template<typename T>
B>class CallOnScopeLeave
B>{
B>   typedef int (__stdcall *func_type)(T); // int & stdcall need for calling Win API
B>   func_type Func;
B>   T Param;
B>public:
B>   CallOnScopeLeave(func_type func, T par) : Func(func), Param(par) {};
B>   ~CallOnScopeLeave()
B>   {
B>      Func(Param);
B>   };
B>};
B>


B>Используется, понятное дело, так:


B>
B>HANDLE hFile = CreaterFile(...);
B>if (hFile == INVALID_HANDLE_VALUE) 
B>   return;
B>CallOnScopeLeave<HANDLE>(&CloseHandle, hFile);
B>// работа с хэндлом...
B>


B>А вопрос такой. Наверняка эт не я один умный , и такие шаблоны уже существует. Линканите плз какой-нибудь более-менее известный и стандартный. (Без заточки под винду, как у меня, да и вообще хочется посмотреть на "тру" RAII-шаблон )


Сыроватый у тебя шаблон получился: CallOnScopeLeave не запрещает создание новых копий объекта, которые при своем уничтожении будут закрывать один и тот же хендл. Чтобы довести дело до логического завершения нужно либо запретить копирование для CallOnScopeLeave, либо корректно организовать подсчет ссылок и выполнять закрытие хендла с разрушением последнего объекта.

А из существующих, пожалуй, наиболее известными являются boost::scoped_ptr (монопольное владение) и boost::shared_ptr (совместное владение).
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Шаблон для идиомы RAII
От: Кодт Россия  
Дата: 28.12.09 17:03
Оценка:
Здравствуйте, denisko, Вы писали:

D>shared_ptr со заданным деструктором?


Только если даннай хэндл является указателем. А что делать с числами? Зверски кастить к void* и обратно?

Лучше написать и отполировать свой велосипед.
Тем более, что не так уж там много нужно для полировки.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[3]: Шаблон для идиомы RAII
От: rusted Беларусь  
Дата: 28.12.09 17:46
Оценка:
Здравствуйте, Кодт, Вы писали:

D>>shared_ptr со заданным деструктором?


К>Только если даннай хэндл является указателем. А что делать с числами? Зверски кастить к void* и обратно?


К>Лучше написать и отполировать свой велосипед.

К>Тем более, что не так уж там много нужно для полировки.

Можно еще через вот такое умбо-юмбо: http://www.revergestudios.com/reblog/index.php?n=ReCode.SharedPtrHandles
Хоть я и не хотел бы столкнуться с таким трюком в рабочем проекте, но сама идея интересная.
Re[3]: Шаблон для идиомы RAII
От: denisko http://sdeniskos.blogspot.com/
Дата: 28.12.09 19:58
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, denisko, Вы писали:


D>>shared_ptr со заданным деструктором?


К>Только если даннай хэндл является указателем. А что делать с числами? Зверски кастить к void* и обратно?


К>Лучше написать и отполировать свой велосипед.

К>Тем более, что не так уж там много нужно для полировки.
Несколько возражений.
1) Семантически любой Хендл является указателем с флагами.Так что совесть зверский каст оправдает.
2) Можно принимать указатель на хендл, который валяется рядом стеке. Вероятность того, что он запорется, а содержимое shared/scoped ptr останется в целости и сохранности стремительно стремится.
3) Автор, судя по стилю, не сильно склонен заморачиваться с спецификацией исключений и explicitamи. А это вторые и третьи грабли после тех, которые укзазал rg45. Если они начнут срабатывать когда кодом будет пользоваться не только он один, его будут бить. Возможно, даже ногами.
<Подпись удалена модератором>
Re[4]: Шаблон для идиомы RAII
От: denisko http://sdeniskos.blogspot.com/
Дата: 28.12.09 20:04
Оценка:
Здравствуйте, rusted, Вы писали:

R>Здравствуйте, Кодт, Вы писали:


D>>>shared_ptr со заданным деструктором?


К>>Только если даннай хэндл является указателем. А что делать с числами? Зверски кастить к void* и обратно?


К>>Лучше написать и отполировать свой велосипед.

К>>Тем более, что не так уж там много нужно для полировки.

R>Можно еще через вот такое умбо-юмбо: http://www.revergestudios.com/reblog/index.php?n=ReCode.SharedPtrHandles

R>Хоть я и не хотел бы столкнуться с таким трюком в рабочем проекте, но сама идея интересная.
Ты не поверишь, это каноническое использование shared_ptr'a.
<Подпись удалена модератором>
Re[5]: Шаблон для идиомы RAII
От: rusted Беларусь  
Дата: 28.12.09 20:45
Оценка:
Здравствуйте, denisko, Вы писали:

R>>Можно еще через вот такое умбо-юмбо: http://www.revergestudios.com/reblog/index.php?n=ReCode.SharedPtrHandles

R>>Хоть я и не хотел бы столкнуться с таким трюком в рабочем проекте, но сама идея интересная.
D>Ты не поверишь, это каноническое использование shared_ptr'a.

С таким каноническим использованием появляется дополнительный уровень косвенности там, где он не нужен, а объем дополнительного кода не намного меньше, чем в случае своего специального маленького велосипедика.
Re[5]: Шаблон для идиомы RAII
От: Тот кто сидит в пруду Россия  
Дата: 28.12.09 21:20
Оценка:
Здравствуйте, denisko, Вы писали:

К>>>Только если даннай хэндл является указателем. А что делать с числами? Зверски кастить к void* и обратно?


К>>>Лучше написать и отполировать свой велосипед.

К>>>Тем более, что не так уж там много нужно для полировки.

R>>Можно еще через вот такое умбо-юмбо: http://www.revergestudios.com/reblog/index.php?n=ReCode.SharedPtrHandles

R>>Хоть я и не хотел бы столкнуться с таким трюком в рабочем проекте, но сама идея интересная.
D>Ты не поверишь, это каноническое использование shared_ptr'a.

Не поверю. В случае с хэндлом исключена ситуация с циклическими ссылками, поэтому не надо предусматривать возможность реализации weak_ptr, поэтому нет необходимости держать shared_count в отдельном блоке памяти. Иными словами, если уж пришла в голову странная идея изваять обертку для хэндлов из смартпойнтера, делать ее лучше не из shared_ptr, a из intrusive_ptr — меньшее количество раз память выделять придется.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: Шаблон для идиомы RAII
От: Xeor Россия  
Дата: 28.12.09 21:45
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Не поверю. В случае с хэндлом исключена ситуация с циклическими ссылками, поэтому не надо предусматривать возможность реализации weak_ptr, поэтому нет необходимости держать shared_count в отдельном блоке памяти.


Борьба с циклическими ссылками — не единственный способ применения weak_ptr. Например есть ещё signals2::slot.track()
Re: Шаблон для идиомы RAII
От: Bell Россия  
Дата: 29.12.09 03:05
Оценка: 5 (2)
Здравствуйте, Basil2, Вы писали:

Например http://www.ddj.com/cpp/184403758
Любите книгу — источник знаний (с) М.Горький
Re[6]: Шаблон для идиомы RAII
От: Юрий Жмеренецкий ICQ 380412032
Дата: 29.12.09 05:01
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

D>>Ты не поверишь, это каноническое использование shared_ptr'a.


ТКС>Не поверю. В случае с хэндлом исключена ситуация с циклическими ссылками, поэтому не надо предусматривать возможность реализации weak_ptr, поэтому нет необходимости держать shared_count в отдельном блоке памяти. Иными словами, если уж пришла в голову странная идея изваять обертку для хэндлов из смартпойнтера, делать ее лучше не из shared_ptr, a из intrusive_ptr — меньшее количество раз память выделять придется.


shared_ptr поддерживает разные экземпляры deleter'a (stateful), тогда как intrusive_ptr — только 'один' (stateless), поэтому сравнивать на лучше/хуже не совсем корректно. Можно посмотреть на unique_ptr из C++0X, у которого есть возможность использования в двух вариантах — статически заданный deleter (один на все объекты), и вариант с ссылкой на него (каждый объект может иметь собственный deleter). Здесь есть реализация.
Re: Шаблон для идиомы RAII
От: jazzer Россия Skype: enerjazzer
Дата: 29.12.09 07:26
Оценка:
Здравствуйте, Basil2, Вы писали:

B>А вопрос такой. Наверняка эт не я один умный , и такие шаблоны уже существует. Линканите плз какой-нибудь более-менее известный и стандартный. (Без заточки под винду, как у меня, да и вообще хочется посмотреть на "тру" RAII-шаблон )


Boost.ScopeExit
http://www.boost.org/libs/scope_exit/doc/html/index.html

Boost.SmartPtr
http://www.boost.org/libs/smart_ptr/sp_techniques.html#on_block_exit
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Шаблон для идиомы RAII
От: denisko http://sdeniskos.blogspot.com/
Дата: 29.12.09 09:00
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:


ТКС>Не поверю.

Написать свой делетер -- это не каноническое использование?


ТКС>В случае с хэндлом исключена ситуация с циклическими ссылками, поэтому не надо предусматривать возможность реализации weak_ptr, поэтому нет ТКС>необходимости держать shared_count в отдельном блоке памяти.

Аппетит приходит во время еды. Вполне вероятна ситуация, в которой надо управлять временем жизни некоторого разделяемого хендла, получить который от системы было довольно затратно. Разумно расширить наш велосипед и на эту область, а не делать новый. Далее, вероятна ситуация, когда вызов метода какого-нибудь объекта в скопе приведет к тому, что защищаемый хендл сохранится внутрях этого объекта. Это ошибка человека, который проектировал объект, но ошибка достаточно трудноуловимая (кто его знает , когда он этот хендл дернет) и, повторюсь, вероятная. Использование shared_ptr позволит такие ошибки словить достаточно просто.
ТКС> делать ее лучш не из shared_ptr, a из intrusive_ptr — меньшее количество раз память выделять придется.
Тут даже соглашусь, с маленькой оговоркой -- "Евреи, не жалейте заварки".
<Подпись удалена модератором>
Re[7]: Шаблон для идиомы RAII
От: Тот кто сидит в пруду Россия  
Дата: 29.12.09 10:06
Оценка: +2
Здравствуйте, denisko, Вы писали:

ТКС>>Не поверю.

D>Написать свой делетер -- это не каноническое использование?

Использовать умный указатель для управления временем жизни сущностей, не имеющих семантики указателя — не каноническое использование.

ТКС>>В случае с хэндлом исключена ситуация с циклическими ссылками, поэтому не надо предусматривать возможность реализации weak_ptr, поэтому нет ТКС>необходимости держать shared_count в отдельном блоке памяти.

D>Аппетит приходит во время еды. Вполне вероятна ситуация, в которой надо управлять временем жизни некоторого разделяемого хендла, получить который от системы было довольно затратно. Разумно расширить наш велосипед и на эту область, а не делать новый. Далее, вероятна ситуация, когда вызов метода какого-нибудь объекта в скопе приведет к тому, что защищаемый хендл сохранится внутрях этого объекта. Это ошибка человека, который проектировал объект, но ошибка достаточно трудноуловимая (кто его знает , когда он этот хендл дернет) и, повторюсь, вероятная. Использование shared_ptr позволит такие ошибки словить достаточно просто.

Код, иллюстрирующий указанную ситуацию, можете предложить? А я потом объясню, как там обойтись без shared_ptr А то софистикой заниматься лениво.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: Шаблон для идиомы RAII
От: Кодт Россия  
Дата: 29.12.09 11:10
Оценка:
Здравствуйте, denisko, Вы писали:

D>1) Семантически любой Хендл является указателем с флагами.Так что совесть зверский каст оправдает.


Необязательно. А если это куки какой-то сессии?
Куки обычно бывают
— указателями
— числами
— UIDами
— строками

В случае GUID сложно кастить его к указателю и обратно — разве что это будет честный указатель на new GUID. Впрочем, "евреи, не жалейте заварки".

D>2) Можно принимать указатель на хендл, который валяется рядом стеке. Вероятность того, что он запорется, а содержимое shared/scoped ptr останется в целости и сохранности стремительно стремится.


Это очевидная ситуация scope guard, так что scoped_ptr / unique_ptr наше всё.
Использование shared_ptr в данном случае избыточно и ошибкоопасно.

D>3) Автор, судя по стилю, не сильно склонен заморачиваться с спецификацией исключений и explicitamи. А это вторые и третьи грабли после тех, которые укзазал rg45. Если они начнут срабатывать когда кодом будет пользоваться не только он один, его будут бить. Возможно, даже ногами.


Но если заморочится, то это и будет та самая необходимая полировка.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[4]: Шаблон для идиомы RAII
От: Basil2 Россия https://starostin.msk.ru
Дата: 29.12.09 12:02
Оценка:
Здравствуйте, denisko, Вы писали:

D>3) Автор, судя по стилю, не сильно склонен заморачиваться с спецификацией исключений и explicitamи. А это вторые и третьи грабли после тех, которые укзазал rg45. Если они начнут срабатывать когда кодом будет пользоваться не только он один, его будут бить. Возможно, даже ногами.


Хм, а зачем там спецификация исключений и explicit?!

Исключения не предполагаются; "throw()" скорее штука вредная; explicit имеет смысл для конструктора с одним аргументом.
Разве что запретить копирование стоит...
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[2]: Шаблон для идиомы RAII
От: Basil2 Россия https://starostin.msk.ru
Дата: 29.12.09 12:05
Оценка:
Здравствуйте, rg45, Вы писали:

R>А из существующих, пожалуй, наиболее известными являются boost::scoped_ptr (монопольное владение) и boost::shared_ptr (совместное владение).


Эти-то понятное дело. Но мой взгляд это форменное извращение — пихать в указатель, пусть и умный, объект указателем не являющийся, да еще и с дополнительной обкладкой в виде user-defined делетера. Я предполагал, что просто существует аналог моего шаблона, только отполированный (я, например, как ты справедливо заметил, не прикрутил запрет копирования).
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[2]: Шаблон для идиомы RAII
От: Basil2 Россия https://starostin.msk.ru
Дата: 29.12.09 12:21
Оценка:
Здравствуйте, jazzer, Вы писали:

B>>А вопрос такой. Наверняка эт не я один умный , и такие шаблоны уже существует. Линканите плз какой-нибудь более-менее известный и стандартный. (Без заточки под винду, как у меня, да и вообще хочется посмотреть на "тру" RAII-шаблон )


J>Boost.ScopeExit

J>http://www.boost.org/libs/scope_exit/doc/html/index.html

Дык я, собственно, как на ScopeExit посмотрел, так сразу и понял что надо делать свое

ScopeExit некрасив, использует макросы и генерит скрытый код. А мне нужно тупо вызвать CloseHandle() по окончанию блока, и все. Я и сделал, фактически, тот же ScopeExit, но для _одной_ функции и потому куда как более простой. Однако мой шаблон заточен именно под виндовый CloseHandle(). В частности, в нем даже прописано что функция возвращает int (т.е. виндовый BOOL), т.к. именно это CloseHandle() и возвращает. Т.е. как минимум для универсальности надо добавить в параметры шаблона возвращаемое значение, как-то избавиться от __stdcall (или не надо?), запретить копирование.

Мне казалось, что кто-нибудь это уже проделал...
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[3]: Шаблон для идиомы RAII
От: Кодт Россия  
Дата: 29.12.09 14:51
Оценка: +1
Здравствуйте, Basil2, Вы писали:

B>Я предполагал, что просто существует аналог моего шаблона, только отполированный (я, например, как ты справедливо заметил, не прикрутил запрет копирования).


Существуют, конечно, и даже в public domain, на RSDN порыться если... Каждый core programmer просто обязан написать такую штуку.
(Только мне, если честно, сейчас не до грибов — искать. Помню, что уже не единожды было. Да и сам писал, с разной степенью кудрявости).
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[3]: Шаблон для идиомы RAII
От: Юрий Жмеренецкий ICQ 380412032
Дата: 29.12.09 15:38
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Здравствуйте, jazzer, Вы писали:


B>>>А вопрос такой. Наверняка эт не я один умный , и такие шаблоны уже существует. Линканите плз какой-нибудь более-менее известный и стандартный. (Без заточки под винду, как у меня, да и вообще хочется посмотреть на "тру" RAII-шаблон )


J>>Boost.ScopeExit

J>>http://www.boost.org/libs/scope_exit/doc/html/index.html

B>Дык я, собственно, как на ScopeExit посмотрел, так сразу и понял что надо делать свое


B>ScopeExit некрасив, использует макросы и генерит скрытый код. А мне нужно тупо вызвать CloseHandle() по окончанию блока, и все. Я и сделал, фактически, тот же ScopeExit, но для _одной_ функции и потому куда как более простой. Однако мой шаблон заточен именно под виндовый CloseHandle(). В частности, в нем даже прописано что функция возвращает int (т.е. виндовый BOOL), т.к. именно это CloseHandle() и возвращает. Т.е. как минимум для универсальности надо добавить в параметры шаблона возвращаемое значение, как-то избавиться от __stdcall (или не надо?), запретить копирование.


B>Мне казалось, что кто-нибудь это уже проделал...


В качестве идеи:


#include <boost/aligned_storage.hpp>
#include <boost/static_assert.hpp>
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include <iostream>

namespace detail {

struct holder_base
{
    virtual ~holder_base(){}
};

template<class T>
struct holder : holder_base
{
    holder(const T& v) : functor(v) {}
    
    ~holder() {
        functor();
    }
    
    T functor;
};

template<std::size_t size>
struct on_scope_exit_base : boost::noncopyable
{
    template<class functor>
    on_scope_exit_base(const functor& e) {
        BOOST_STATIC_ASSERT(size > sizeof holder<functor>);
        ::new(this->data.address()) holder<functor>(e);
    }
    
    ~on_scope_exit_base() {
        static_cast<holder_base*>(this->data.address())->~holder_base();
    }

    boost::aligned_storage<size> data;
};

} // detail

typedef detail::on_scope_exit_base<32> on_scope_exit;



void print(int v)
{
    std::cout << v << std::endl;
}

void test(bool e)
{
    try
    {
        on_scope_exit print10 = boost::bind(&print, 10);
        
        if(e)
            throw 1;

        std::cout << 2 << std::endl;
    }
    catch(...)
    {
        std::cout << "e" << std::endl;
    }
}


int main()
{
    test(true);
    std::cout << "--" << std::endl;
    test(false);
}

/*
    10
    e
    --
    2
    10
*/
Re[3]: Шаблон для идиомы RAII
От: jazzer Россия Skype: enerjazzer
Дата: 30.12.09 04:41
Оценка: +1
Здравствуйте, Basil2, Вы писали:

B>Здравствуйте, jazzer, Вы писали:


B>>>А вопрос такой. Наверняка эт не я один умный , и такие шаблоны уже существует. Линканите плз какой-нибудь более-менее известный и стандартный. (Без заточки под винду, как у меня, да и вообще хочется посмотреть на "тру" RAII-шаблон )


J>>Boost.ScopeExit

J>>http://www.boost.org/libs/scope_exit/doc/html/index.html

B>Дык я, собственно, как на ScopeExit посмотрел, так сразу и понял что надо делать свое


B>ScopeExit некрасив, использует макросы и генерит скрытый код.

К сожалению, без этого пока что не обойтись из-за ограничений языка, если мы хотим иметь возможность исполнять при выходе произвольный код.
В С++0х будет легче.

B>А мне нужно тупо вызвать CloseHandle() по окончанию блока, и все. Я и сделал, фактически, тот же ScopeExit, но для _одной_ функции и потому куда как более простой.


Пока тебе достаточно просто звать функцию без параметров — да, Boost.ScopeExit будет оверкиллом.
Но как только тебе понадобится нечто посложнее (например, та же функция, но срабатывающая в зависимости от флага — стандартная ситуация) — ты проклянешь все, пытаясь собрать функтор при помощи Boost.Bind/Boost.Lambda. Не говоря уже о читабельности того, что у тебя получится, в сравнении с Boost.ScopeExit.

B>Мне казалось, что кто-нибудь это уже проделал...


shared_ptr, я же дал ссылку на их страничку, посвященную именно этому.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Шаблон для идиомы RAII
От: Alexander G Украина  
Дата: 30.12.09 07:48
Оценка: 37 (2)
Здравствуйте, denisko, Вы писали:

К>>Лучше написать и отполировать свой велосипед.

К>>Тем более, что не так уж там много нужно для полировки.
D>Несколько возражений.
D>1) Семантически любой Хендл является указателем с флагами.Так что совесть зверский каст оправдает.

Возвращаемый AcquireCredentialsHandle даже по размеру больше указателя.

нет, если shared_ptr использовать, то стоит биндить хендл в удалитель.
void FreeHandle(int h);

int main()
{
  int handle = 3;
  boost::shared_ptr<void const> p("", boost::bind(FreeHandle, handle));
}



D>2) Можно принимать указатель на хендл, который валяется рядом стеке. Вероятность того, что он запорется, а содержимое shared/scoped ptr останется в целости и сохранности стремительно стремится.


ничего не понял.

D>3) Автор, судя по стилю, не сильно склонен заморачиваться с спецификацией исключений и explicitamи. А это вторые и третьи грабли после тех, которые укзазал rg45. Если они начнут срабатывать когда кодом будет пользоваться не только он один, его будут бить. Возможно, даже ногами.


explicit конечно нужен. а спецификация исключений — нет.
Русский военный корабль идёт ко дну!
Re[5]: Шаблон для идиомы RAII
От: Basil2 Россия https://starostin.msk.ru
Дата: 30.12.09 14:32
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>explicit конечно нужен. а спецификация исключений — нет.


Зачем там нужен explicit?
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re[4]: Шаблон для идиомы RAII
От: Basil2 Россия https://starostin.msk.ru
Дата: 30.12.09 14:39
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Пока тебе достаточно просто звать функцию без параметров — да, Boost.ScopeExit будет оверкиллом.

J>Но как только тебе понадобится нечто посложнее (например, та же функция, но срабатывающая в зависимости от флага — стандартная ситуация) — ты проклянешь все, пытаясь собрать функтор при помощи Boost.Bind/Boost.Lambda. Не говоря уже о читабельности того, что у тебя получится, в сравнении с Boost.ScopeExit.

Для "посложнее" я просто напишу новый конструктор, который будет принимать ф-цию с двумя параметрами

B>>Мне казалось, что кто-нибудь это уже проделал...

J>shared_ptr, я же дал ссылку на их страничку, посвященную именно этому.

Реально в тему дал ссылку пользователь Bell, а ссылка такая:
http://www.ddj.com/cpp/184403758

Там действительно именно то, что я хотел.
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
Re: Шаблон для идиомы RAII
От: artiz  
Дата: 04.01.10 13:43
Оценка: 2 (1)
Здравствуйте, Basil2, Вы писали:

B>Чисто чтобы не забывать закрывать виндовые хендлы, набросал примитивный шаблон:


B>А вопрос такой. Наверняка эт не я один умный , и такие шаблоны уже существует. Линканите плз какой-нибудь более-менее известный и стандартный. (Без заточки под винду, как у меня, да и вообще хочется посмотреть на "тру" RAII-шаблон )


Вот еще мои велосипедики — util.guards.hpp

Я там еще reset()/release() прикручивал, как у auto_ptr — может пригодится.
Re[8]: Шаблон для идиомы RAII
От: denisko http://sdeniskos.blogspot.com/
Дата: 06.01.10 15:50
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Код, иллюстрирующий указанную ситуацию, можете предложить? А я потом объясню, как там обойтись без shared_ptr А то софистикой заниматься лениво.

Пожалте.
void someFunction()
{
ResourceGuard someResource;
anotherManFunction(someResource);//вот тут товарищь кешировал у себя значение, хранимое
                                // в someResource и через некоторое время начинал себя странно вести. 
                                // Предложи код, который бы мог отследить незаконный захват ресурса товарищем, 
                                 //если товарищ имеет использовать и клонировать только обертку но не сам ресурс.


}
<Подпись удалена модератором>
Re[9]: Шаблон для идиомы RAII
От: Тот кто сидит в пруду Россия  
Дата: 06.01.10 19:43
Оценка:
Здравствуйте, denisko, Вы писали:

D>Здравствуйте, Тот кто сидит в пруду, Вы писали:


ТКС>>Код, иллюстрирующий указанную ситуацию, можете предложить? А я потом объясню, как там обойтись без shared_ptr А то софистикой заниматься лениво.

D>Пожалте.
D>
D>void someFunction()
D>{
D>ResourceGuard someResource;
D>anotherManFunction(someResource);//вот тут товарищь кешировал у себя значение, хранимое
D>                                // в someResource и через некоторое время начинал себя странно вести. 
D>                                // Предложи код, который бы мог отследить незаконный захват ресурса товарищем, 
D>                                 //если товарищ имеет использовать и клонировать только обертку но не сам ресурс.


D>}

D>


Если товарищ запасает голый хэндл, то shared_ptr с закрывателем хэндла ему все равно не поможет (т.к. защищаемый хэндл все равно закроется при разрушении someResource). Если же он пытается сохранить ResourceGuard, то ситуация просто не попадает под определение "когда вызов метода какого-нибудь объекта в скопе приведет к тому, что защищаемый хендл сохранится внутрях этого объекта". Так что извольте другой пример.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: Шаблон для идиомы RAII
От: andrey_nado  
Дата: 08.01.10 10:38
Оценка: +2
Здравствуйте, Basil2, Вы писали:

B>Используется, понятное дело, так:

B>
B>CallOnScopeLeave<HANDLE>(&CloseHandle, hFile);
B>


Могу ошибаться, но по-моему правильно использовать так:

B>
B>CallOnScopeLeave<HANDLE> anyName(&CloseHandle, hFile);
B>


В Вашем же случае анонимный объект удаляется в месте объявления.
Re[6]: Шаблон для идиомы RAII
От: Alexander G Украина  
Дата: 08.01.10 10:43
Оценка:
Здравствуйте, Basil2, Вы писали:

B>Зачем там нужен explicit?


Чтобы избежать неявного конструирования из хендла, владение которым не должно передаваться.
Русский военный корабль идёт ко дну!
Re[7]: Шаблон для идиомы RAII
От: Basil2 Россия https://starostin.msk.ru
Дата: 11.01.10 11:08
Оценка: 1 (1)
Здравствуйте, Alexander G, Вы писали:

B>>Зачем там нужен explicit?


AG>Чтобы избежать неявного конструирования из хендла, владение которым не должно передаваться.


Как вы представляете неявное конструирование от конструктора с _двумя_ аргументами??
Или я что-то недопонимаю в С++?..
Проект Ребенок8020 — пошаговый гайд как сделать, вырастить и воспитать ребенка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.