Информация об изменениях

Сообщение Re[9]: Как изменить цвет кнопки? от 23.11.2019 9:23

Изменено 23.11.2019 9:28 Carc

Re[9]: Как изменить цвет кнопки?
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Carc, Вы писали:


C>> enum {TMT_AFTERHIDE=100, TMT_AFTERSHOW=400};


ЕМ>Хм, а какой смысл пару обычных констант с явными значениями определять через enum?

Code Style. Стив Макконнел.

Следует избегать непонятных значений. В случае enum мы получаем те же же самые именнованные константы, которые явно своим именем говорят, за что они отвечают.
  • Код яснее и понятнее.
  • Константы определены в одном месте, а не размазаны где-то по коду ниже. Такой код легко сопровождать\модифицировать. Не нужно копаться в кишках кода ниже, где суть вся. (SendMessage, Sleep). В моем случае ведь "кишки" и могут меняться: PostMessage вместо Send***, WaitForObject***, вместо Sleep и.т.д Но это детали. Они где-то там внизу кода. Суть вверху — все сразу ясно и понятно.
  • И потом: вот enum это RVALUE. Причем жесткий такой RVALUE. Здесь не получатся танцы с бубном, вроде const_cast, или взять адрес.

    Простой пример: допустим такой таймаут должен передеваться как in\out параметр еще в какую функцию. Ок! Все передается, все зер-гут. Даже если мы забыли объявить нашу константу как const UINT наш_таймаут...

    Дальше сосед по цеху, слегка по пьяни, меняет объявление своей функции. И она получает уже не константную ссылку наconst UINT&, а просто ссылку UINT&. Ну приспичило ему, рефакторинг-развитие-кода-in\out_параметр-все-дела — нужное подчеркнуть…
    И упс, ранее наш работающий код летит в тартарары…

    В случаем с enum такого не случится. Не скомилится и всё тут.

    PS: а вообще юзанье анонимного enum — великое дело для читабельности кода.
    Яркий пример, который люблю юзать налево и направо в многопоточном коде, это ожидание на парочке хендлов.
    
    
    HANDLE hForWait[2];
    hForWait[0]=hAppClosed;
    hForWait[1]=hПоСути_там_чего_то_где-то_ну_вроде_данные_с_сервера_пришли;
    
    const DWORD dwWT=WaitForMultipleObjects(ARRAYSIZE(hForWait), hForWait,…);
    
    //и вот тут вот уже нужно помнить, какой хендл сигналит\помер, какой хендл первый в массиве, какой второй - не дай бог ошибиться.
    switch(dwWT) {
    case dwWT-WAIT_FOR_OBJECT_0:
    …
    case dwWT-WAIT_ABANDONED_0 :
    }

    А можно переписать на enum именование.
    Нужно всего лишь все аккуратно проинициализировать в начале, дальше код сам себя поддерживает
    
    enum {H_APP_CLOSED=0, H_EVENT=1}
    HANDLE hForWait[2];
    hForWait[H_APP_CLOSED]=hAppClosed;
    hForWait[H_EVENT]=hПоСути_там_чего_то_где-то_ну_вроде_данные_с_сервера_пришли;
    
    const DWORD dwWT=WaitForMultipleObjects(ARRAYSIZE(hForWait), hForWait,…);
    
    //ВУАЛЯ
    //все явно - и все видно!!! какой хендл просигналил
    switch(dwWT - WAIT_FOR_OBJECT_0) {
    case H_APP_CLOSED:
    …
    case H_EVENT:
    }
  • Re[9]: Как изменить цвет кнопки?
    Здравствуйте, Евгений Музыченко, Вы писали:

    ЕМ>Здравствуйте, Carc, Вы писали:


    C>> enum {TMT_AFTERHIDE=100, TMT_AFTERSHOW=400};


    ЕМ>Хм, а какой смысл пару обычных констант с явными значениями определять через enum?

    Code Style. Стив Макконнел.

    Следует избегать непонятных значений. В случае enum мы получаем те же же самые именнованные константы, которые явно своим именем говорят, за что они отвечают.
  • Код яснее и понятнее.
  • Константы определены в одном месте, а не размазаны где-то по коду ниже. Такой код легко сопровождать\модифицировать. Не нужно копаться в кишках кода ниже, где суть вся. (SendMessage, Sleep). В моем случае ведь "кишки" и могут меняться: PostMessage вместо Send***, WaitForObject***, вместо Sleep и.т.д Но это детали. Они где-то там внизу кода. Суть вверху — все сразу ясно и понятно.
  • И потом: вот enum это RVALUE. Причем жесткий такой RVALUE. Здесь не получатся танцы с бубном, вроде const_cast, или взять адрес.

    Простой пример: допустим такой таймаут должен передеваться как in параметр еще в какую функцию. Ок! Все передается, все зер-гут. Даже если мы забыли объявить нашу константу как const UINT наш_таймаут...

    Дальше сосед по цеху, слегка по пьяни, меняет объявление своей функции. Теперь это не in, а in\out параметр.
    И функция получает уже не константную ссылку на const UINT&, а просто ссылку UINT&.

    Ну приспичило ему, рефакторинг-развитие-кода-in\out_параметр-все-дела — нужное подчеркнуть…
    И упс, ранее наш работающий код летит в тартарары…

    В случаем с enum такого не случится. Не скомилится и всё тут.

    PS: а вообще юзанье анонимного enum — великое дело для читабельности кода.
    Яркий пример, который люблю юзать налево и направо в многопоточном коде, это ожидание на парочке хендлов.
    
    
    HANDLE hForWait[2];
    hForWait[0]=hAppClosed;
    hForWait[1]=hПоСути_там_чего_то_где-то_ну_вроде_данные_с_сервера_пришли;
    
    const DWORD dwWT=WaitForMultipleObjects(ARRAYSIZE(hForWait), hForWait,…);
    
    //и вот тут вот уже нужно помнить, какой хендл сигналит\помер, какой хендл первый в массиве, какой второй - не дай бог ошибиться.
    switch(dwWT) {
    case dwWT-WAIT_FOR_OBJECT_0:
    …
    case dwWT-WAIT_ABANDONED_0 :
    }

    А можно переписать на enum именование.
    Нужно всего лишь все аккуратно проинициализировать в начале, дальше код сам себя поддерживает
    
    enum {H_APP_CLOSED=0, H_EVENT=1}
    HANDLE hForWait[2];
    hForWait[H_APP_CLOSED]=hAppClosed;
    hForWait[H_EVENT]=hПоСути_там_чего_то_где-то_ну_вроде_данные_с_сервера_пришли;
    
    const DWORD dwWT=WaitForMultipleObjects(ARRAYSIZE(hForWait), hForWait,…);
    
    //ВУАЛЯ
    //все явно - и все видно!!! какой хендл просигналил
    switch(dwWT - WAIT_FOR_OBJECT_0) {
    case H_APP_CLOSED:
    …
    case H_EVENT:
    }