15. Активно используйте const
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 не является необходимым ни для кэшированной информации, ни для неизменного указателя на нее.
Модификатор const напоминает вирусное заболевание — появившись в вашем коде один раз, он приведет к необходимости соответствующего изменения сигнатур функций, которые еще не являются корректными в плане использования const. Это как раз не ошибка, а хорошее свойство, существенно увеличивающее мощь модификатора const, который еще не так давно был достаточно заброшен, а его возможности не вполне поняты и оценены. Переделка существующего кода для его корректности в плане использования const требует усилий, но они стоят того и даже позволяют выявить скрытые ошибки.
Корректное применение const дает отличные результаты и повышает эффективность. Чрезвычайно важно правильно и последовательно использовать модификатор const в ваших программах. Понимание того, как и где изменяется состояние программы, особенно необходимо, а модификатор const по сути документирует непосредственно в коде программы, где именно компилятор может помочь вам в этом. Правильное употребление const поможет вам лучше разобраться с вопросами проектирования и сделать ваш код более надежным и безопасным. Если вы выяснили, что некоторую функцию-член невозможно сделать константной, значит, вы более детально разобрались с тем, как, где и почему эта функция модифицирует состояние объекта. Кроме того, вы сможете понять, какие члены-данные объединяют физическую и логическую константность (см. приведенные ниже примеры).
Никогда не прибегайте к преобразованию константного типа в неконстантный, кроме случаев вызова функции, некорректной в плане использования модификатора const (не модифицирующей параметр, который тем не менее описан как неконстантный), а также такого редкого случая, как способ замены mutable в старом компиляторе, не поддерживающем эту возможность.
Примеры
Пример. Избегайте const в объявлениях функций, принимающих параметры по значению. Два следующих объявления абсолютно эквивалентны:
void Fun(int x);
void Fun(const int x); // Объявление той же самой функции:
// const здесь игнорируется
Во втором объявлении модификатор const избыточен. Мы рекомендуем объявлять функции без таких высокоуровневых модификаторов const, чтобы тот, кто читает ваши заголовочные файлы, не был дезориентирован. Однако использование такого модификатора имеет значение в определении функции и его применение может быть оправдано с точки зрения обнаружения непреднамеренного изменения переданного параметра:
void Fun(const int x) { // определение функции Fun
// ...
++x; // Ошибка: нельзя изменять константное значение
// ...
}
Ссылки
[Allison98] §10 • [Cline99] §14.02-12 • [Dewhurst03] §6, §31-32, §82 • [Keffer95] pp. 5-6 • [Koenig97] §4 • [Lakos96] §9.1.6, §9.1.12 • [Meyers97] §21 • [Murray93] §2.7 • [Stroustrup00] §7.2, §10.2.6, §16.3.1 • [Sutter00] §43
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Используйте с умом
Используйте с умом Как и все блестящие новые инструменты, переходы стоит использовать там, где они уместны. Очень легко нарушить чувство меры и добавить переходы ко всем элементам на странице, таким образом превратив ее в раздражающего пульсирующего монстра. Очень
Еще раз: используйте с умом
Еще раз: используйте с умом Потратив немного времени на размышления о смысле содержимого, с которым мы работаем, мы можем выбрать некоторые свойства CSS3, которые функционируют сегодня, вместе с переходами и преобразованиями.Такие улучшения взаимодействия могут быть
8.5. Используйте WPA или WPA2
8.5. Используйте WPA или WPA2 Протоколы WPA (Wi-Fi Protected Access), WPA2 и WEP (Wired Equivalent Privacy) обеспечивают защиту и шифрование данных, передаваемых беспроводным маршрутизатором и беспроводным клиентом. Предпочтительнее использовать WPA2, но если этот протокол устройством не поддерживается,
Используйте отступы!
Используйте отступы! Правильное использование отступов служит основой создания понятного программного кода. В примере из предыдущего раздела каждая пара операторов, определяющих одну структуру, напечатана с одним и тем же отступом. При наличии отступов проще выяснить,
94. Избегайте преобразований, отменяющих const
94. Избегайте преобразований, отменяющих const РезюмеПреобразование типов, отменяющее const, может привести к неопределенному поведению, а кроме того, это свидетельство плохого стиля программирования даже в том случае, когда применение такого преобразования вполне
97. Не используйте объединения для преобразований
97. Не используйте объединения для преобразований РезюмеХитрость все равно остается ложью: объединения можно использовать для получения "преобразования типа без преобразования", записывая информацию в один член и считывая из другого. Однако это еще более опасно и менее
19.2.3.2. Используйте автоинструменты GNU
19.2.3.2. Используйте автоинструменты GNU Определение конфигурационных параметров должно быть выполнено во время компиляции. Значительное преимущество дистрибутивов с открытым исходным кодом заключается в том, что они позволяют адаптировать пакет к обнаруженной среде на
Правило 2: Предпочитайте const, enum и inline использованию #define
Правило 2: Предпочитайте const, enum и inline использованию #define Это правило лучше было бы назвать «Компилятор предпочтительнее препроцессора», поскольку #define зачастую вообще не относят к языку C++. В этом и заключается проблема. Рассмотрим простой пример; попробуйте написать
Правило 3: Везде, где только можно используйте const
Правило 3: Везде, где только можно используйте const Замечательное свойство модификатора const состоит в том, что он накладывает определенное семантическое ограничение: данный объект не должен модифицироваться, – и компилятор будет проводить это ограничение в жизнь. const
Правило 20: Предпочитайте передачу по ссылке на const передаче по значению
Правило 20: Предпочитайте передачу по ссылке на const передаче по значению По умолчанию в C++ объекты передаются в функции и возвращаются функциями по значению (свойство, унаследованное от C). Если не указано противное, параметры функции инициализируются копиями реальных
19.2.3.2. Используйте автоинструменты GNU
19.2.3.2. Используйте автоинструменты GNU Определение конфигурационных параметров должно быть выполнено во время компиляции. Значительное преимущество дистрибутивов с открытым исходным кодом заключается в том, что они позволяют адаптировать пакет к обнаруженной среде на
Модификаторы const и volatile
Модификаторы const и volatile Модификатор const не допускает явного присваивания значения переменной либо других косвенных действий по изменению ее значения, таких как выполнение операций инкремента и декремента. Значение указателя, объявленного с модификатором const, не может
3.5. Спецификатор const
3.5. Спецификатор const Возьмем следующий пример кода:for ( int index = 0; index 512; ++index )... ;С использованием литерала 512 связаны две проблемы. Первая состоит в легкости восприятия текста программы. Почему верхняя граница переменной цикла должна быть равна именно 512? Что скрывается за