Стандарты программирования на С++. 101 правило и рекомендация - страница 21
. Заметим, что если все закрытые члены скрыты с использованием идиомы 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
16. Избегайте макросов
Макрос — самый неприятный инструмент С и С++, оборотень, скрывающийся под личиной функции, кот, гуляющий сам по себе и не обращающий никакого внимания на границы ваших областей видимости. Берегитесь его!
Трудно найти язык, достаточно красочный, чтобы выразить все, что хочется сказать о макросах. Но тем не менее приведем несколько цитат.
Макросы по многим причинам — весьма неприятная вещь, которая может стать попросту опасной. В первую очередь это связано с тем, что макросы — средство замены текста, действующее во время обработки исходного текста препроцессором, т.е. еще до того, как начнется какая-либо проверка синтаксиса и семантики.
— [Sutter04] §31
Мне не нравится большинство видов препроцессоров и макросов. Одна из целей С++ — сделать препроцессор С излишним (§4.4, §18), поскольку я считаю его большой ошибкой
— [Stroustrup94] §3.3.1.
Макросы почти никогда не являются необходимыми в С++. Используйте >const
(§5.4) или >enum
(§4.8) для определения явных констант [см. рекомендацию 15], >inline
(§7.1.1) для того, чтобы избежать накладных расходов на вызов функции [но см. рекомендацию 8],