Re[5]: Покритикуйте код
От: watchmaker  
Дата: 06.02.15 13:00
Оценка:
Здравствуйте, CEMb, Вы писали:

MD>>А что меняет слово static?


CEM>я делаю инициализацию объекта в конструкторе. Но для статика явного конструктора нет.


Ну-ка, распиши всё же подробнее чем тебе static мешает использовать RAII? Никому ведь не мешает, а тебе мешает. Чем же твой код такой особенный? :)
Нет конструктора — ну так напиши его. Собственно как делается во всех случаях.
Re[3]: Покритикуйте код
От: Кодт Россия  
Дата: 06.02.15 15:55
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Ну я обычно так и делаю, но тут static


А что, статик как-то радикально меняет дело?
struct doit {};

struct AllMyRaiiStuff
{
  CHandle h1, h2, h3; // каждый сам по себе умеет очищаться

  AllMyRaiiStuff() {}
  AllMyRaiiStuff(doit) { init(); }

  void init()
  {
    h1 = Init1(); h2 = Init2(); h3 = Init3();
  }
};

static AllMyRaiiStuff all_my_raii_stuff;

bool init_all()
{
  try
  {
    all_my_raii_stuff = std::move( AllMyRaiiStuff(doit()) ); // выполняем init() и завершаем транзакцию
    return true;
  }
  catch(...)
  {
    return false;
  }
}

bool init_all_another_way()
{
  try
  {
    all_my_stuff.init(); // выполняем init() не атомарно...
    return true;
  }
  catch(...)
  {
    all_my_stuff = std::move( AllMyRaiiStuff() ); // одним махом откатываем
    return false;
  }
}


Только если лень переписывать код, нацарапанный карандашом на столешнице.
Перекуём баги на фичи!
Re[6]: Покритикуйте код
От: CEMb  
Дата: 06.02.15 18:47
Оценка:
Здравствуйте, watchmaker, Вы писали:

CEM>>я делаю инициализацию объекта в конструкторе. Но для статика явного конструктора нет.


W>Ну-ка, распиши всё же подробнее чем тебе static мешает использовать RAII? Никому ведь не мешает, а тебе мешает. Чем же твой код такой особенный?

W>Нет конструктора — ну так напиши его. Собственно как делается во всех случаях.

я не пойму как, можно пример?
Re[4]: Покритикуйте код
От: CEMb  
Дата: 06.02.15 19:02
Оценка:
Здравствуйте, Кодт, Вы писали:

CEM>>Ну я обычно так и делаю, но тут static


К>А что, статик как-то радикально меняет дело?


А, ну вот теперь понятно, предлагается обернуть всё статическое в один класс и на нём уже RAII.
Спасибо, подумаю, как это прикрутить в моём случае. У меня статический вектор указателей на сам класс, который надо загрузить из файла. Добавлять ещё один класс ради правильной инициализации просто одного вектора как-то не хочется. Но, возможно, у меня неправильная архитектура, надо подумать ещё раз и переделать, спасибо.
Re: Покритикуйте код
От: omgOnoz  
Дата: 09.02.15 03:42
Оценка: +1
Здравствуйте, CEMb, Вы писали:

CEM>Почитал соседнюю ветку, и вспомнилось...


CEM>Принцип создания функции инициализации:


  Скрытый текст
CEM>
CEM>BOOL CApp::InitCommon()
CEM>{
CEM>    try
CEM>    {
CEM>        if(!m_zero.InitCommon())
CEM>            throw 0;
CEM>        if(!m_one.InitCommon())
CEM>            throw 1;
CEM>        if(!m_two.InitCommon())
CEM>            throw 2;
CEM>        //...
CEM>    }
CEM>    catch(int iExc)
CEM>    {
CEM>        switch(iExc)
CEM>        {
CEM>        //...
CEM>        case 3:
CEM>            m_two.UninitCommon();
CEM>        case 2:
CEM>            m_one.UninitCommon();
CEM>        case 1:
CEM>            m_zero.UninitCommon();
CEM>        }
CEM>        return FALSE;
CEM>    }
CEM>    return TRUE;
CEM>}
CEM>

CEM>у меня конкретно в коде были вызовы статических методов классов для инициализации общих данных, (через C:: ).



CEM>чтоб понятнее, в чём суть, лучше так:


  Скрытый текст
CEM>
CEM>BOOL CApp::Init()
CEM>{
CEM>    try
CEM>    {
CEM>        m_hSome0 = InitSome0()
CEM>        if (!m_hSome0)
CEM>            throw 0;
CEM>        m_hSome1 = InitSome1()
CEM>        if (!m_hSome1)
CEM>            throw 1;
CEM>        m_hSome2 = InitSome2()
CEM>        if (!m_hSome2)
CEM>            throw 2;
CEM>        //...
CEM>    }
CEM>    catch(int iExc)
CEM>    {
CEM>        switch(iExc)
CEM>        {
CEM>        //...
CEM>        case 3:
CEM>            Release(hSome2);
CEM>        case 2:
CEM>            Release(hSome1);
CEM>        case 1:
CEM>            Release(hSome0);
CEM>        }
CEM>        return FALSE;
CEM>    }
CEM>    return TRUE;
CEM>}
CEM>



CEM>Часто в примерах встречал код, который инициализировал некоторые члены класса один за другим, в случае ошибки делал деинициализацию уже готовых. В результате к хвосту функции число вызова деинициализаторов было велико. Ну и повторы кода на каждом условии.

CEM>Как вариант, люди использовали некую булеву переменную для понимания, что инициализации идут хорошо, каждая новая инициализация обкладывалась условием на эту переменную. В конце эта переменная проверялась, если false, то проверялись опять же все хендлы на валидность, и делалась деинициализация.
CEM>Мне кажется, мой код проще и нагляднее, быстро расширяется, можно не бояться забыть, что что-то пропустил.
CEM>Жду: критику, доработку, идеи

Сделать uninit / release — который ничего не делает, если ресурс не был выделен.
Если тебе так хочется JavaStyle — то пусть эксепшн кидают InitCommon / InitSome0 — а в catch вызываеться — UninitCommon() -> который вызовет m_two.UninitCommon() и т.п.

BOOL CApp::InitCommon()
{
    try
    {
        m_zero.InitCommon();
        m_one.InitCommon();
        m_two.InitCommon();
    }
    catch(ExpectedException ee)
    {
        LogError(ee);
        UninitCommon();
        return FALSE;
    }
    return TRUE;
}

void CApp::UninitCommon() 
{
    m_two.UninitCommon();
    m_one.UninitCommon();
    m_zero.UninitCommon();
}

Или вообще в место BOOL — кидать исключения ->

void CApp::InitCommon()
{
    try
    {
        m_zero.InitCommon();
        m_one.InitCommon();
        m_two.InitCommon();
    }
    catch(ExpectedException ee)
    {
        LogError(ee);
        UninitCommon();
        throw ExpectedException(ee);
    }
}

void CApp::UninitCommon() 
{
    m_two.UninitCommon();
    m_one.UninitCommon();
    m_zero.UninitCommon();
}
Отредактировано 09.02.2015 3:48 omgOnoz . Предыдущая версия . Еще …
Отредактировано 09.02.2015 3:45 omgOnoz . Предыдущая версия .
Отредактировано 09.02.2015 3:44 omgOnoz . Предыдущая версия .
Отредактировано 09.02.2015 3:42 omgOnoz . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.