Стандарты программирования на С++. 101 правило и рекомендация | страница 41
Каждый дополнительный уровень вложенности приводит к излишним интеллектуальным нагрузкам при чтении кода, поскольку при этом требуется хранить в памяти "стек" наподобие "вошли в цикл… вошли в блок >try
… вошли в условный оператор… еще в один цикл…". Вам никогда не приходилось продираться сквозь сложный код и искать, какой же именно из множества конструкций >for
, >whilе
и т.п. соответствует вот эта закрывающая фигурная скобка? Более хорошее и продуманное разложение задачи на функции позволит читателю вашей программы одновременно удерживать в голове существенно больший контекст.
Воспользуйтесь здравым смыслом. Ограничивайте длину и глубину ваших функций. Далее приведены некоторые добрые советы, которые помогут вам в этом.
• Предпочитайте связность. Пусть одна функция решает только одну задачу (см. рекомендацию 5).
• Не повторяйтесь. Следует предпочесть именованную функцию повтору схожих фрагментов кода.
• Пользуйтесь оператором >&&
. Избегайте вложенных последовательных конструкций >if
там, где их можно заменить оператором >&&
.
• Не нагружайте >try
. Предпочитайте использовать освобождение ресурсов в деструкторах, а не в >try
-блоках (см. рекомендацию 13).
• Пользуйтесь алгоритмами. Они короче, чем рукописные циклы, и зачастую лучше и эффективнее (см. рекомендацию 84).
• Не используйте >switch
для дескрипторов типов. Применяйте вместо этого полиморфные функции (см. рекомендацию 90).
Функция может на законных основаниях быть длинной и/или глубокой, если ее функциональность нельзя разумно разделить на отдельные подзадачи, поскольку каждое такое потенциальное разделение требует передачи массы локальных переменных и контекста (что приводит к еще менее удобочитаемому результату). Но если несколько таких потенциальных функций получают аналогичные аргументы, они могут быть кандидатами в члены нового класса.
[Piwowarski82] • [Miller56]
21. Избегайте зависимостей инициализаций между единицами компиляции
Объекты уровня пространств имен в разных единицах компиляции не должны зависеть друг от друга при инициализации, поскольку порядок их инициализации не определен. В противном случае вам обеспечена головная боль при попытках разобраться со сбоями в работе программы после внесения небольших изменений в ваш проект и невозможностью его переноса даже на новую версию того же самого компилятора.
Когда вы определяете два объекта уровня пространства имен в разных единицах компиляции, конструктор какого из объектов будет вызван первым, не определено. Чаще всего (но не всегда) ваш инструментарий будет инициализировать их в том порядке, в котором компонуются скомпилированные объектные файлы, но полагаться на это предположение нельзя, даже если оно и выполняется, — вы же не хотите, чтобы корректность вашей программы зависела от вашего файла проекта или