Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Баланс


Автор: xTr1m 21.5.2012, 13:35
Доброго времени суток. В последнее время заметил за собой одну вещь, которая мне не нравится. В погоне за универсальностью и гибкостью (как мне кажется =)) я часто увлекаюсь и получается крайне непонятный с первого взгляда (а некоторым и с пятого) код. Например, я пытаюсь увязать некую информацию об объекте через std::map и получаю объявления вида
Код

// <элемент интерфейса, <наименование реквизита, атрибут за который он отвечает>>
typedef std::map<CWnd*, std::pair<CString, CAttr*>> TWndEntryNameReferences;

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

P.S. самому мне кажется, что тут должен быть какой-то баланс, но сам я его не чувствую. Спасибо.

Автор: bsa 21.5.2012, 14:04
Цитата(xTr1m @  21.5.2012,  14:35 Найти цитируемый пост)
все же лучше писать максимально понятный код. 

Баланс быть должен. Но начинать всегда надо именно с понятного кода. Например, в твоем случае std::pair использовать нет никакого смысла. Лучше под это вообще отдельную структуру выделить с адекватными названиями полей.

Автор: borisbn 21.5.2012, 14:06
Кто-то из классиков (Александреску, кажется) говорил (не цитирую, а по памяти):
Цитата
Код нужно писать так, как будто сопровождать его после тебя будет маньяк-убийца, который, к тому же, знает твой домашний адрес.


Честно говоря, не вижу в приведённом примере ничего страшного. Тем более, что рядом стоит понятный и подробный комментарий.
Если же при использовании ты пишешь как-то так:
Код
TWndEntryNameReferences::const_iterator foundIt = the_map.find( hWnd );
if ( foundIt != the_map.end() ) {
    const TWndEntryNameReferences::mapped_type & found = (*foundIt).second;
    const CString & name = found.first;
    const CAttr * attr = found.second;
// дальше работа только с name и attr
    doSomething( name, attr );
}

а не так
Код
TWndEntryNameReferences::const_iterator foundIt = the_map.find( hWnd );
if ( foundIt != the_map.end() ) {
    doSomething( foundIt->second.first, foundIt->second.second );
}

то вообще никаких проблем не вижу

Автор: xTr1m 21.5.2012, 14:51
bsa, это для меня всегда было вопросом. То есть, если есть две переменные, то что лучше: пара и отдельная структура. Структура вроде бы понятней, но нужно ее объявить, обнулить переменные, а иногда нужна не структура, а класс, значит еще и конструктор (иногда деструктор). А пара она, вроде как, лаконичней.

borisbn, как раз частенько получается как во втором варианте, так как, например, foundIt->second.second используется только один раз, то я всегда думал, что нет нужды объявлять ссылку и тут же ее передавать. Как тут быть?

Автор: borisbn 21.5.2012, 15:01
xTr1m, эта ссылка как раз "именует" поле std::pair'а. Нормальный компилятор на 99,9(9)% превратит это в  foundIt->second.second.
Зато тому, кто будет читать код, не потребуется лезть в объявление map'а, чтобы посмотреть, что же там за тип, и что написано в комментарии по поводу значений этого типа.
И потом, ты ж наверняка знаешь и такое изречение: "Код гораздо чаще читается, чем компилируется" (как-то так, за точность не ручаюсь). Так что, делай код понятным. Не экономь на размере исходника, и тебе не будет страшен Александресковский маньяк-убийца ))

Автор: xTr1m 21.5.2012, 15:05
Цитата

Нормальный компилятор на 99,9(9)% превратит это в  foundIt->second.second


вот за это спасибо. очень хороший аргумент, буду знать, что говорить в таких случаях =))

Автор: xTr1m 21.5.2012, 15:43
Кстати, а действительно ли данное утверждение у указателям?

Автор: borisbn 21.5.2012, 16:01
Цитата(xTr1m @  21.5.2012,  15:43 Найти цитируемый пост)
действительно ли данное утверждение у указателям?

В исполняемом коде ссылка и указатель - одно и то же. Отличаются они только синтаксисом использования на языке высокого уровня. Так что с указателем должно быть всё то же самое, что и с ссылкой.
И вообще (раз уж начинать цитировать классиков) "преждевременная оптимизация - источник многих бед"

Автор: Леопольд 21.5.2012, 20:43
Цитата(xTr1m @  21.5.2012,  13:35 Найти цитируемый пост)
я, конечно, оставляю комментарии, но все равно. мне как-то пришлось править код, который я писал год назад. и мне понадобилось минут 20, чтобы понять,что к чему. Зато сама переделка потребовала минимум кода и в одном месте.

Пиши подробные doxygen комментарии и генери документацию, тогда быстрее поймёшь что к чему.

Автор: borisbn 22.5.2012, 10:02
Хорошо, что есть такие люди, как Result - единственный не посмеялся, а указал мне на глупость...

да, конечно же, не Александреску, а Макконелл говорил про маньяка
Цитата
«Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете» — Стив Макконнелл.


Result, спасибо за поправочку.

Автор: xvr 22.5.2012, 11:03
Я обычно использую pair<> (в таких случаях) только если эта структура данных используется локально - в пределах одной/двух функций (или методах). Если больше, и тем более, если выходит во внешний интерфейс класса (или модуля), то делаю отдельную структуру

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)