Russian Qt Forum
Май 06, 2024, 20:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Класс автоматического взведения и сброса флага  (Прочитано 18923 раз)
SASA
Гость
« : Август 24, 2010, 09:11 »

Код:
#ifndef FLAGASSISTANT_H
#define FLAGASSISTANT_H

/// Дефайн для быстрого взведения флага спомощью класса CFlagAssistant.
#define COCKFLAG(flagName) CFlagAssistant flagAssistant(&flagName);

/*! \brief Класс автоматического взведения и сброса флага.
* \author SASA.
* \date 2010/08/18
*/
class CFlagAssistant
{
public:
/*! \brief Конструктор.
* \param[in] _flag (\c bool *) - Указатель на флаг, за которым следим.
*/
CFlagAssistant(bool * _flag)
{
m_flag = _flag;
if(m_flag) *m_flag = true;
}
~CFlagAssistant()
{
if(m_flag) *m_flag = false;
}
protected:
bool * m_flag; ///< Флаг за которым следим.
};

#endif // FLAGASSISTANT_H

Использование.

Код:
class MyClass
{
public:
MyClass()
{
m_flag = false;
}
/*! Пока исполняется этот метод, флаг должен быть взведённым.
* После выхода из метода, флаг должен сброситься.
*/
void metod()
{
COCKFLAG(m_flag);
много кода c несколькими ретурнами;
}
protected:
m_flag;
};

Самое главное, что изменив код метода (добавив ещё один ретурн) нам не надо писать строку m_flag = false; А про неё так легко забыть Улыбающийся А есть ещё исключения, по которым функция может прерваться где угодно. Класс позволяет легко сохранить условие, описанное в комментарии.

З.Ы. О валидности указателя надо заботиться самим. Буду рад услышать предложения о повышении безопастности
Записан
spectre71
Гость
« Ответ #1 : Сентябрь 04, 2010, 23:32 »

А если флаг был == true, что получится при выходе Улыбающийся

И вообще интереснее установка флага в конкретное значение (true/false)
« Последнее редактирование: Сентябрь 04, 2010, 23:38 от Spectre » Записан
SASA
Гость
« Ответ #2 : Сентябрь 05, 2010, 13:24 »

А если флаг был == true, что получится при выходе Улыбающийся

И вообще интереснее установка флага в конкретное значение (true/false)
Что Вы имеете в виду.
Записан
SABROG
Гость
« Ответ #3 : Сентябрь 05, 2010, 18:52 »

Что Вы имеете в виду.

Вероятно то, что у тебя нигде флаг не устанавливается в 0. Вроде как стандарт C++ инициализирует нулями только POD типы и не факт, что класс является POD типом.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #4 : Сентябрь 06, 2010, 00:04 »

... не факт, что класс является POD типом.

Данный класс (CFlagAssistant) точно не является POD типом.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Denjs
Гость
« Ответ #5 : Сентябрь 06, 2010, 00:25 »

гм... можно "человеческими" словами описать за какой надобностью данный класс нужен?
ну т.е. бизнес-профит? бизнес-задача или системная задача которую решает данный класс? а то как-то я затрудныюсь понять зачем мне например данный класс может быть полезен? за каком флагом мы следим? зачем его быстро возводим? и т.п.... ? Непонимающий

UPD: через некоторое время разбора кода понял, что класс предназначен для "автоматического" сброса|устновки значения переменной по выходу из процедуры или участка кода в "{}"  - что бы не восстанавливать старое значение руками.
да?

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

Заранее спасибо.
« Последнее редактирование: Сентябрь 06, 2010, 00:52 от Denjs » Записан
SASA
Гость
« Ответ #6 : Сентябрь 06, 2010, 17:39 »

да?
Да.
По-моему я всё опсиал. Класс простенький - описание простенькое.

Логика работы аналогична QMutexLocker.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Сентябрь 07, 2010, 12:19 »

У меня есть такой же класс, называется CAutoFlag, (правда указатель но ноль я не проверяю). Штучка малюсенькая но удобная. Без нее получается коряво, напр.

Код
C++ (Qt)
void MyClass::CalcSomething( void )
{
mPortalActive = true;
if (!Check1()) {
 mPortalActive = false;
 return;
}
...
if (!Check2()) {
 mPortalActive = false;
 return;
}
...
 mPortalActive = false;
}
 
С классом приятнее
Код
C++ (Qt)
void MyClass::CalcSomething( void )
{
CAutoFlag theFlag(&mPortalActive);
if (!Check1())
 return;
...
if (!Check2())
 return;
...
}
 
« Последнее редактирование: Сентябрь 07, 2010, 13:21 от Igors » Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #8 : Сентябрь 08, 2010, 19:13 »

Обощим идею Подмигивающий Пример использования в каментах ниже

Код
C++ (Qt)
#pragma once
 
/*! Use this scoped class to temporarely change some value and restore old value
   when scope out.
 
\code
bool block;
{
    scoped_value_change<bool> s(block, true, block);
    ...
}
...
std::string status;
{
    scoped_value_change<std::string> s(flag, "entered", "leaved");
    ...
}
 
\endcode
*/

template <typename T>
class scoped_value_change
{
public:
   scoped_value_change(T& value, const T& in, const T& out)
   : value_(value), out_(out)
   {
       value_ = in;
   }
 
   ~scoped_value_change()
   {
       value_ = out_;
   }
private:
   T& value_;
   T out_;
};
 
« Последнее редактирование: Сентябрь 08, 2010, 19:16 от navrocky » Записан

Гугль в помощь
spectre71
Гость
« Ответ #9 : Сентябрь 09, 2010, 10:14 »

А если флаг был == true, что получится при выходе Улыбающийся

И вообще интереснее установка флага в конкретное значение (true/false)
Что Вы имеете в виду.

bool MyFlg1 = true;
bool MyFlg2 = false;

{
  COCKFLAG(MyFlg1);
  COCKFLAG(MyFlg2);

//MyFlg1 == true;
//MyFlg2 == true;
...
...

}

//MyFlg1 == false;
//MyFlg2 == false;


//MyFlg1 должен быть равен true !!!

Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #10 : Сентябрь 09, 2010, 10:55 »

//MyFlg1 должен быть равен true !!!

В моем варианте это решено:
Код:
bool my_flag = true;
{
    scoped_value_change<bool> sv(my_flag, false, my_flag);
    // my_flag = false
}
// my_flag = true
Записан

Гугль в помощь
SASA
Гость
« Ответ #11 : Сентябрь 09, 2010, 14:04 »

Обощим идею Подмигивающий

Мне нравится. Но я бы добавил макрос типа COCKFLAG.
Почему он нужен? Потому что две следущие строки очень похожи, а поведение прямо противоволожное.

Код:
scoped_value_change<bool> s(block, true, block);

Код:
scoped_value_change<bool>(block, true, block);

И по смыслу более логично. Я хочу написать строчку со смыслом "Взведи флаг, который автоматом сброситься". А не "Заведи переменную, которая мне потом не нужна, которая взведет флаг и потом его сбросит".


Записан
Akon
Гость
« Ответ #12 : Сентябрь 09, 2010, 15:31 »

Обощим идею Подмигивающий Пример использования в каментах ниже

Код
C++ (Qt)
#pragma once
 
/*! Use this scoped class to temporarely change some value and restore old value
   when scope out.
 
\code
bool block;
{
    scoped_value_change<bool> s(block, true, block);
    ...
}
...
std::string status;
{
    scoped_value_change<std::string> s(flag, "entered", "leaved");
    ...
}
 
\endcode
*/

template <typename T>
class scoped_value_change
{
public:
   scoped_value_change(T& value, const T& in, const T& out)
   : value_(value), out_(out)
   {
       value_ = in;
   }
 
   ~scoped_value_change()
   {
       value_ = out_;
   }
private:
   T& value_;
   T out_;
};
 

Более-менее окончательный вариант.
Я бы добавил еще простой конструктор (частный случай), оставляющий исходное значение:
Код:
scoped_value_change(T& value, const T& out)
: value_(value), out_(out)
{
}

Ну и оптимизация. Что лучше: 1) const T& out или 2) T out - зависит от Т. boost::call_traits<T>::param_type - будет передавать либо по ссылке, либо по значению (истинное обобщение  Улыбающийся).   
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


Просмотр профиля
« Ответ #13 : Сентябрь 09, 2010, 15:33 »

Цитировать
Мне нравится. Но я бы добавил макрос типа COCKFLAG.
Согласен, на базе этого можно наплодить дефайнов, упрощающих часто используемые вызовы.

Цитировать
Я бы добавил еще простой конструктор (частный случай), оставляющий исходное значение:
Да!

Цитировать
boost::call_traits
Таки тоже да!

Результат:
Код
C++ (Qt)
#pragma once
 
#include <boost/call_traits.hpp>
 
/*! Use this scoped class to temporarely change some value and restore old value
   when scope out.
 
\code
bool flag;
{
    scoped_value_change<bool> s(flag, true, flag);
    ...
    // or
    scoped_value_change<bool> s(flag, true);
    ...
 
    // or even
    SCOPE_COCK_FLAG(flag);
    ...
}
\endcode
*/

 
/*! Temporarely set a flag to true and return old flag value when the scope is out.*/
#define SCOPE_COCK_FLAG(flag) scoped_value_change<bool> __sv_##flag(flag, true)
 
/*! Temporarely set a flag to false and return old flag value when the scope is out.*/
#define SCOPE_RESET_FLAG(flag) scoped_value_change<bool> __sv_##flag(flag, false)
 
template <typename T>
class scoped_value_change
{
public:
   typedef typename boost::call_traits<T>::reference reference;
   typedef typename boost::call_traits<T>::param_type param;
 
   scoped_value_change(reference value, param in)
   : value_(value), out_(value)
   {
       value_ = in;
   }
 
   scoped_value_change(reference value, param in, param out)
   : value_(value), out_(out)
   {
       value_ = in;
   }
 
   ~scoped_value_change()
   {
       value_ = out_;
   }
private:
   reference value_;
   T out_;
};
 
« Последнее редактирование: Сентябрь 09, 2010, 15:57 от navrocky » Записан

Гугль в помощь
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #14 : Сентябрь 09, 2010, 16:04 »

не ребят, у вас явно уже ум за разум заходит... больше буста
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.226 секунд. Запросов: 22.