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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Класс автоматического взведения и сброса флага  (Прочитано 19989 раз)
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


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

кыш на С программировать  Подмигивающий
Записан

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

Сообщений: 11445


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

Конечно template привлекателен своей универсальностью/общностью. Но в то же время он затрудняет понимание, при использовании приходится тратить усилия и время чтобы вспомнить. Я лично ни разу не сталкивался с необходимость авто-сброса никакой др. переменной кроме булевской. Как и с ситуацией "флаг уже установлен". Делать общее решение "на всякий случай" мне кажется неэффективным, оно должно созреть. вызываться практикой
Записан
ритт
Гость
« Ответ #17 : Сентябрь 14, 2010, 20:11 »

на данную тему - вот у нас имеется реальный пример автовзвода/сброса флага:
Код:
class AutoTransaction
{
public:
    AutoTransaction(QSqlDatabase db) : m_success(true), m_db(db)
    {
        m_db.transaction();
    }

    ~AutoTransaction()
    {
        if (m_success)
            m_db.commit();
        else
            m_db.rollback();
    }

    void setSuccess(bool success)
    {
        m_success = success;
    }

private:
    bool m_success;
    QSqlDatabase m_db;
};

#define EXEC(db, method)   \
    AutoTransaction atr(db); \
    try {                            \
        method;                   \
    } catch(...) {                \
        atr.setSuccess(false); \
        throw;                      \
    }

конечно, эти несколько строк можно было бы и накопипастить везде, где требуется, но так гораздо удобнее, а из-за инлайнов разницы в производительности 0...
Записан
Barmaglodd
Гость
« Ответ #18 : Сентябрь 15, 2010, 09:49 »

Зачем try-catch?
Код:
class AutoTransaction
{
public:
    AutoTransaction(QSqlDatabase db) : m_success(false), m_db(db)
    {
        m_db.transaction();
    }

    ~AutoTransaction()
    {
        if (m_success)
            m_db.commit();
        else
            m_db.rollback();
    }

    void dismiss()    {
        m_success = true;
    }

private:
    bool m_success;
    QSqlDatabase m_db;
};

#define EXEC(db, method)   \
    AutoTransaction atr(db); \
    method;                   \
    atr.dismiss();
Записан
Akon
Гость
« Ответ #19 : Сентябрь 15, 2010, 10:09 »

Присоединяюсь. atr уже не будет доступен при перебросе исключения.
Записан
BRE
Гость
« Ответ #20 : Сентябрь 15, 2010, 10:18 »

atr уже не будет доступен при перебросе исключения.
Почему?
Записан
Akon
Гость
« Ответ #21 : Сентябрь 15, 2010, 11:42 »

Сорри, не совсем понял логику работы.
Тогда лучше вариант Barmaglodd - нет лишнего переброса исключения. А еще лучше scoped-вариант - чтоб после EXEC все реально закончилось.

Код:
#define EXEC(db, method)   \
{ \
    AutoTransaction atr(db); \
    method;                   \
    atr.dismiss();
}
Записан
BRE
Гость
« Ответ #22 : Сентябрь 15, 2010, 11:49 »

Я думаю это специфика проекта, что бы не отпускать исключения вверх.

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

Во всех представленных здесь вариантах исключения прорываются наверх. Так в общем то и задумано, я полагаю; главное, что деструктор AutoTransaction всегда будет вызван. Короче RAII.
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


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

Интересно, а почему метод по смыслу commit назван dismiss? %)
Записан

Гугль в помощь
Akon
Гость
« Ответ #25 : Сентябрь 15, 2010, 12:22 »

Спроси у Barmaglodd. В своем посту я скопипастил.
Записан
SASA
Гость
« Ответ #26 : Сентябрь 15, 2010, 17:00 »

Тепрь я понимаю, как тележка превратилась в БилАз. Смеющийся
Записан
ритт
Гость
« Ответ #27 : Сентябрь 15, 2010, 21:05 »

Зачем try-catch?

если method; выбросит исключение, автоматом откатим транзакцию.
это специфический для приложения макрос, т.к. все ошибки работы с бд, сетью и т.д. выбрасываются в виде исключений...

а вот
Код:
    AutoTransaction atr(db); \
    method;                   \
    atr.dismiss();
это вообще какой-то бред. зачем откатывать, если код отработал успешно?
Записан
navrocky
Гипер активный житель
*****
Offline Offline

Сообщений: 817


Погроммист


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

Бармаглот вообще выдал более красивое решение, только с названием метода ступил...

В деструкторе стекового объекта производится автоматический откат транзакции, если не был вызван метод commit. При исключении commit не будет вызван. Вот и всё, никаких try/catch/rethrow.
Записан

Гугль в помощь
Barmaglodd
Гость
« Ответ #29 : Сентябрь 16, 2010, 11:02 »

это вообще какой-то бред. зачем откатывать, если код отработал успешно?
А внимательно код почитать?

dismiss, т.к. то, что здесь написано, частный случай ScopeGuard. Ну и потом, никто же не запрещает изменить название метода Улыбающийся
« Последнее редактирование: Сентябрь 16, 2010, 11:13 от Barmaglodd » Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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