Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Саттер Герб. Стандарты программирования на С++. 101 правило и рекомендация - royallib.ru.doc
Скачиваний:
58
Добавлен:
11.03.2016
Размер:
715.24 Кб
Скачать

Примеры

Пример 1. Использование инициализирующего значения по умолчанию или оператора ?: для снижения степени смешивания потока данных и потока управления.

// Не рекомендуется: не инициализирует переменную

int speedupFactor;

if (condition)

 speedupFactor = 2;

else

 speedupFactor = -1;

// Лучше: инициализирует переменную

int speedupFactor = -1;

if (condition)

 speedupFactor = 2;

// лучше: инициализирует переменную

int speedupFactor = condition ? 2 : -1;

Варианты, отмеченные как лучшие, не имеют промежутка между определением и инициализацией.

Пример 2. Замена сложных вычислений вызовом функции. Иногда вычисление значения происходит таким образом, что лучше инкапсулировать его в функции (см. рекомендацию 11).

// Не рекомендуется: не инициализирует переменную

int speedupFactor;

if (condition) {

 // ... код ...

 speedupFactor = somevalue;

} else {

 // ... код ...

 speedupFactor = someothervalue;

}

// Лучше: инициализирует переменную

int speedupFactor = ComputeSpeedupFactor();

Пример 3. Инициализация массивов. Для больших составных типов, таких как массивы, корректная инициализация не всегда означает реальное обращение к данным. Пусть, например, вы используете API, который заставляет вас использовать фиксированные массивы char размера МАХ_РАТН (см. рекомендации 77 и 78). Если вы уверены, что массивы всегда будут рассматриваться как строки в стиле С с завершающим нулевым символом, то такого немедленного присваивания будет достаточно:

// Допустимо: Создание пустой строки

char path[MAX_PATH];

path[0] = '\0';

Более безопасная инициализация заполняет все элементы массива нулевыми значениями:

// Лучше: заполняем нулями весь массив

char path[MAX_PATH] = { '\0' };

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

Исключения

Входные буферы и данные, описанные как volatile, которые записываются непосредственно аппаратным обеспечением или другими процессами, не требуют инициализации программой.

Ссылки

[Dewhurst03] §48 • [Stroustrup00] §4.9.5, §6.3

20. Избегайте длинных функций и глубокой вложенности

Резюме

Краткость — сестра таланта. Чересчур длинные функции и чрезмерно вложенные блоки кода зачастую препятствуют реализации принципа "одна функция — одна задача" (см. рекомендацию 5), и обычно эта проблема решается лучшим разделением задачи на отдельные части.

Обсуждение

Каждая функция должна представлять собой связную единицу работы, несущую значимое имя (см. рекомендацию 5 и обсуждение рекомендации 70). Когда функция вместо этого пытается объединить малые концептуальные элементы такого рода в одном большом теле функции, это приводит к тому, что она начинает делать слишком многое.

Чрезмерно большая по размеру функция и чрезмерная вложенность блоков (например, блоков if, for, while и try) делают функции более трудными для понимания и сопровождения, причем зачастую без каких бы то ни было оснований.

Каждый дополнительный уровень вложенности приводит к излишним интеллектуальным нагрузкам при чтении кода, поскольку при этом требуется хранить в памяти "стек" наподобие "вошли в цикл… вошли в блок try… вошли в условный оператор… еще в один цикл…". Вам никогда не приходилось продираться сквозь сложный код и искать, какой же именно из множества конструкций for, whilе и т.п. соответствует вот эта закрывающая фигурная скобка? Более хорошее и продуманное разложение задачи на функции позволит читателю вашей программы одновременно удерживать в голове существенно больший контекст.

Воспользуйтесь здравым смыслом. Ограничивайте длину и глубину ваших функций. Далее приведены некоторые добрые советы, которые помогут вам в этом.

• Предпочитайте связность. Пусть одна функция решает только одну задачу (см. рекомендацию 5).

• Не повторяйтесь. Следует предпочесть именованную функцию повтору схожих фрагментов кода.

• Пользуйтесь оператором && . Избегайте вложенных последовательных конструкций if там, где их можно заменить оператором &&.

• Не нагружайте try . Предпочитайте использовать освобождение ресурсов в деструкторах, а не в try-блоках (см. рекомендацию 13).

• Пользуйтесь алгоритмами. Они короче, чем рукописные циклы, и зачастую лучше и эффективнее (см. рекомендацию 84).

• Не используйте switch для дескрипторов типов. Применяйте вместо этого полиморфные функции (см. рекомендацию 90).