Чтение онлайн

на главную - закладки

Жанры

Стандарты программирования на С++. 101 правило и рекомендация

Александреску Андрей

Шрифт:
Обсуждение

Язык С++ предлагает массу средств для "ускорения" обнаружения ошибок во время компиляции. Использование этих возможностей статических проверок дает массу преимуществ, включая следующие.

• Статические проверки не зависят от данных и логики программы. Статические проверки гарантируют независимость от входных данных программы или потока ее выполнения. В противоположность этому, чтобы убедиться в достаточной строгости тестирования времени выполнения, вы должны проверить его на представительном наборе входных данных. Это достаточно большая и неприятная работа для всех нетривиальных систем.

• Статически выраженные

модели более строги. Зачастую то, что программа полагается на проверки времени компиляции, а не времени выполнения, отражает лучший дизайн, поскольку модель, создаваемая программой, корректно выражена с использованием системы типов С++. Таким образом, вы и компилятор оказываетесь партнерами с общим взглядом на инварианты программ. Зачастую проверки времени выполнения приходится использовать там, где теоретически проверку можно было бы провести статически, но сделать это невозможно из-за ограничений языка программирования (см. рекомендацию 68).

• Статические проверки не приводят к накладным расходам времени выполнения. При замене динамических проверок статическими создаваемая выполнимая программа оказывается быстрее, оставаясь столь же корректной.

Один из наиболее мощных инструментов статических проверок в С++ — статическая проверка типов. Споры о том, должны ли типы проверяться статически (С++, Java, ML, Haskell) или динамически (Smalltalk, Ruby, Python, Lisp), все еще активно продолжаются. В общем случае нет явного победителя, и имеются языки и стили разработки, которые дают хорошие результаты как в одном, так и во втором случае. Сторонники статической проверки аргументируют свою позицию тем, что обработка большого класса ошибок времени выполнения может быть просто устранена, что дает более надежную и качественную программу. Поклонники динамических проверок говорят, что компиляторы способны выявить только часть потенциальных ошибок, так что если вы все равно должны писать тесты для ваших модулей, вы можете вообще не волноваться о статических проверках, получив при этом менее ограничивающую среду программирования.

Понятно одно: в контексте статически типизированного языка С++, обеспечивающего строгую проверку типов и минимальную автоматическую проверку времени выполнения, программисты определенно должны использовать систему типов для своей пользы везде, где только это возможно (см. рекомендации с 90 по 100). В то же время тестирование времени выполнения целесообразно для выполнения проверок, зависящих от данных и потока выполнения программы (например, проверка выхода за границы массива или корректности входных данных) (см. рекомендации 70 и 71).

Примеры

Имеется ряд примеров, где вы можете заменить проверки времени выполнения проверками времени компиляции.

Пример 1. Логические условия времени компиляции. Если вы проверяете логическое условие времени компиляции наподобие

sizeof(int) >= 8
, используйте статические проверки (обратите также внимание на рекомендацию 91).

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

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

Пример 4. Понижающее преобразование типов. Если вы часто используете оператор

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

Исключения

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

assert
(см. рекомендацию 68) и следовать советам из остальной части раздела, посвященного обработке ошибок, для прочих ошибок времени выполнения, таких как ошибки, зависящие от данных (см. рекомендации с 69 по 75).

Ссылки

[Alexandrescu01] §3 • [Boost] • [Meyers97] §46 • [Stroustrup00] §2.4.2 • [Sutter02] §4 • [Sutter04] §2, §19

15. Активно используйте

const

Резюме

const
— ваш друг: неизменяемые значения проще понимать, отслеживать и мотивировать, т.е. там, где это целесообразно, лучше использовать константы вместо переменных. Сделайте
const
описанием по умолчанию при определении значения — это безопасно, проверяемо во время компиляции (см. рекомендацию 14) и интегрируемо с системой типов С++. Не выполняйте преобразований типов с отбрасыванием
const
кроме как при вызове некорректной с точки зрения употребления
const
функции (см. рекомендацию 94).

Обсуждение

Константы упрощают код, поскольку вам достаточно только один раз взглянуть на ее определение, чтобы знать, чему она равна везде. Рассмотрим такой код:

void Fun(vector<int>& v) {

 // ...

 const size_t len = v.size;

 // ... и еще 30 строк ...

}

Увидев такое определение

len
, вы получаете надежную информацию о семантике этой константы в пределах области ее видимости (в предположении, что код не устраняет ее константность, чего он делать не должен, как вы узнаете далее): это информация о длине v в определенной точке программы. Взглянув на одну строку, вы получили всю необходимую информацию для всей области видимости. Если бы переменная
len
не была определена как
const
, она могла бы быть позже изменена — непосредственно или косвенно.

Заметим, что описание

const
не является глубоким. Чтобы понять что имеется в виду, рассмотрим класс
С
, который имеет член типа
X*
. В объекте
С
, который является константой, член
X*
также является константой, но сам объект
X
, на который он указывает, константой не является (см. [Saks99]).

Логическую константность следует реализовывать с использованием членов, описанных как

mutable
. Когда константная функция-член класса оправданно требует модификации переменной-члена (т.е. когда эта переменная не влияет на наблюдаемое состояние объекта, например, если это кэшированные данные), объявите эту переменную-член как
mutable
. Заметим, что если все закрытые члены скрыты с использованием идиомы Pimpl (см. рекомендацию 43), описание
mutable
не является необходимым ни для кэшированной информации, ни для неизменного указателя на нее.

Поделиться:
Популярные книги

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Маглор. Трилогия

Чиркова Вера Андреевна
Маглор
Фантастика:
фэнтези
9.14
рейтинг книги
Маглор. Трилогия

Дурная жена неверного дракона

Ганова Алиса
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Дурная жена неверного дракона

30 сребреников

Распопов Дмитрий Викторович
1. 30 сребреников
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
30 сребреников

Жена проклятого некроманта

Рахманова Диана
Фантастика:
фэнтези
6.60
рейтинг книги
Жена проклятого некроманта

Всадник Системы

Poul ezh
2. Пехотинец Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Всадник Системы

Черный дембель. Часть 5

Федин Андрей Анатольевич
5. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 5

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Измена. Право на любовь

Арская Арина
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на любовь

Тайны затерянных звезд. Том 2

Лекс Эл
2. Тайны затерянных звезд
Фантастика:
боевая фантастика
космическая фантастика
космоопера
фэнтези
5.00
рейтинг книги
Тайны затерянных звезд. Том 2

Как я строил магическую империю 6

Зубов Константин
6. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 6

Поющие в терновнике

Маккалоу Колин
Любовные романы:
современные любовные романы
9.56
рейтинг книги
Поющие в терновнике

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Наследие Маозари 7

Панежин Евгений
7. Наследие Маозари
Фантастика:
боевая фантастика
юмористическое фэнтези
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 7