У меня есть функция t_object get_object ()
t_object это boost::shared_ptr
Все работает, но всем еще надо вызывають read-write локи и ничего не перепутать с разлоками.
Это всё муторно и черевато.
Я хочу написать get_object так , как угодно изменив и добавив
что б object лочила как надо и возвращала.
а когда возвращаемый shared_ptr пропадал и поля видимости и разрушался, что б он еще и разлочивал объект правильно.
С++ старый (VS 2008) и есть boost.
Я могу написать с макросами и BOOST_SCOPE_EXIT но это некрасиво.
Здравствуйте, кубик, Вы писали:
К>Привет,
К>Провожу рефакторинг.
К>У меня есть функция t_object get_object () К>t_object это boost::shared_ptr
К>Все работает, но всем еще надо вызывають read-write локи и ничего не перепутать с разлоками. К>Это всё муторно и черевато. К>Я хочу написать get_object так , как угодно изменив и добавив К>что б object лочила как надо и возвращала. К>а когда возвращаемый shared_ptr пропадал и поля видимости и разрушался, что б он еще и разлочивал объект правильно. К>С++ старый (VS 2008) и есть boost. К>Я могу написать с макросами и BOOST_SCOPE_EXIT но это некрасиво.
Правильно ли я понял ? :
У вас есть класс Foo, у которого есть функции lock/unlock.
typedef boost::shared_ptr<Foo> t_object;
Есть переменная:
t_object m_obj;
Вы хотите чтобы функция get_object() возвращала тот-же объект, указатель на который хранится в m_obj, но предваритено вызвав lock(), и автоматически
вызвать unlock(), когда указатель, возвращенный get_object, перестанет использоваться?
Или мутекс у вас отделен от Foo, и нужно только контролировать время жизни выданного указателя, для вызова unlock?
C>Вы хотите чтобы функция get_object() возвращала тот-же объект, указатель на который хранится в m_obj, но предваритено вызвав lock(), и автоматически C>вызвать unlock(), когда указатель, возвращенный get_object, перестанет использоваться?
C>>Вы хотите чтобы функция get_object() возвращала тот-же объект, указатель на который хранится в m_obj, но предваритено вызвав lock(), и автоматически C>>вызвать unlock(), когда указатель, возвращенный get_object, перестанет использоваться?
К>Да, вот правильно.
Вообще-то он предназначен для создания указания на члены класса, хранимого под умным указателем. Но для "пометки" указателей возвращенных функцией он тоже сгодится.
Здравствуйте, кубик, Вы писали:
C>>Вы хотите чтобы функция get_object() возвращала тот-же объект, указатель на который хранится в m_obj, но предваритено вызвав lock(), и автоматически C>>вызвать unlock(), когда указатель, возвращенный get_object, перестанет использоваться? К>Да, вот правильно.
Так можно сделать, завернув shared_ptr в ещё один смарт-указатель, но практика показывает, что удобнее и безопаснее вместо функции get_object() написать функцию transform(Fn functor), которая в качестве параметра принимает функтор и исполняет его с данными которые лочатся до вызова функтора и разлочиваются после окончания его исполнения:
template<typename T>
class SafeData
{
public:
template<class Fn>
auto Transform(Fn&& op)
{
std::lock_guard<std::mutex> lock( mtx );
return op(data);
}
private:
std::mutex mtx;
T data;
};
Здравствуйте, кубик, Вы писали:
К>Здравствуйте, Chorkov, Вы писали:
C>>Тогда нужно воспользоваться специальным конструктором std::shared_ptr C>>( он 8-й в списке https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr )
К>Ойейей, это какое то новое С++ , а 8й коннструктор вообще из C++20. К>Нельзя ли по другому как угодно изменив get_object и его параметры?
Там два 8-х конструктора. Для до c++20 и после.
(В с++20 заменили const shared_ptr<Y>& на shared_ptr<Y>&& )
Этот конструктор был сразу.
Здравствуйте, B0FEE664, Вы писали:
BFE>Это близкая к реальному коду иллюстрация идеи.
Только надо помнить про блокировку чтобы внутри лямбды дедлок не устроить.
Здравствуйте, Kernan, Вы писали:
BFE>>Это близкая к реальному коду иллюстрация идеи. K>Только надо помнить про блокировку чтобы внутри лямбды дедлок не устроить.
C>>Вы хотите чтобы функция get_object() возвращала тот-же объект, указатель на который хранится в m_obj, но предваритено вызвав lock(), и автоматически C>>вызвать unlock(), когда указатель, возвращенный get_object, перестанет использоваться?
К>Да, вот правильно.
Что делается с этим shared_ptr там, откуда вызывается get_object()?
Думаю, лучше убрать вообще get_object() и добавить в класс, в котором определена переменная m_obj, функцию, которая будет выполнять требуемые действия и вызывать lock()/unlock() для объекта.