void concatUnsafePtr(std::string* ps1,
 std::string* ps2, std::string* pout) {
 *pout = *ps1 + *ps2;
}
Здесь такая же проблема, как в примере с concatUnsafe, описанном ранее. Добавьте const для гарантии невозможности обновления исходных строк.
void concatSaferPtr(const std::string* ps1,
 const std::string* ps2, std::string* pout) {
 *pout = *ps1 + *ps2;
}
Отлично, теперь вы не можете изменить *ps1 и *ps2. Но вы по- прежнему можете изменить ps1 и ps2, или, другими словами, используя их, вы можете сослаться на какую-нибудь другую строку, изменяя значение указателя, но не значение, на которое он ссылается. Ничто не может помешать вам, например, сделать следующее.
void concatSaferPtr(const std:string* ps1,
 const std::string* ps2, std::string* pout) {
 ps1 = pout; // Ух!
 *pout = *ps1 + *ps2;
}
Предотвратить подобные ошибки можно с помощью еще одного const.
void concatSafestPtr(const std::string* const ps1,
 const std::string* const ps2, std::string* pout) {
 *pout = *ps1 + *ps2;
}
Применение const по обе стороны звездочки делает вашу функцию максимально надежной. В этом случае вы ясно показываете свои намерения пользователям вашей функции, и ваша репутация не пострадает в случае описки.
Рецепт 15.4.
15.4. Обеспечение невозможности модификации своих объектов в функции-члене
Требуется вызывать функции -члены для константного объекта, но ваш компилятор жалуется на то, что он не может преобразовать тип используемого вами объекта из константного в неконстантный.
Поместите ключевое слово const справа от имени функции-члена при ее объявлении в классе и при ее определении. Пример 15.4 показывает, как это можно сделать
#include <iostream>
#include <string>
class RecordSet {
public:
 bool getFieldVal(int i, std::string& s) const;
 // ...
};
bool RecordSet::getFieldVal(int i, std::string& s) const {
 // Здесь нельзя модифицировать никакие неизменяемые
 // данные-члены (см. обсуждение)
}
void displayRecords(const RecordSet& rs) {
 // Здесь вы можете вызывать только константные функции-члены
 // для rs
}
Добавление концевого const в объявление члена и в его определение заставляет компилятор более внимательно отнестись к тому, что делается с объектом внутри тела члена. Константным функциям-членам не разрешается выполнять неконстантные операции с данными-членами. Если такие операции присутствуют, компиляция завершится неудачно. Например, если бы в RecordSet::getFieldVal я обновил счетчик-член, эта функция не была бы откомпилирована (в предположении, что getFieldCount_ является переменной-членом класса RecordSet).
bool RecordSet::getFieldVal(int i, std::string& s) const {
 ++getFieldCount_; // Ошибка: константная функция-член не может
                   // модифицировать переменную-член
                   // ...
}
Это может также помочь обнаружить более тонкие ошибки, подобно тому, что делает const в роли квалификатора переменной (см. рецепт 15.3). Рассмотрим следующую глупую ошибку.
bool RecordSet::getFieldVal(int i, std::string& s) const {
 fieldArray_[i] = s; // Ой, я не это имел в виду
 // ...
}
Снова компилятор преждевременно завершит работу и выдаст сообщение об ошибке, потому что вы пытаетесь изменить переменную-член, а это не разрешается делать в константных функциях-членах. Ну, при одном исключении.
В классе RecordSet (в таком, как (схематичный) класс в примере 15.4) вам, вероятно, потребовалось бы перемещаться туда-сюда по набору записей, используя понятие «текущей» записи. Простой способ заключается в применении переменной-члена целого типа, содержащей номер текущей записи; ваши функции-члены, предназначенные для перемещения текущей записи вперед-назад, должны увеличивать или уменьшать это значение.
void RecordSet::gotoNextPecord() const {
 if (curIndex_ >= 0 && curIndex_ < numRecords_-1)
  ++curIndex_;
}
void RecordSet::gotoPrevRecord() const {
 if (curIndex_ > 0)
  --curIndex_;
}
Очевидно, что это не сработает, если эти функции-члены являются константными. Обе обновляют данное-член. Однако без этого пользователи класса RecordSet не смогут перемещаться по объекту const RecordSet. Это исключение из правил работы с константными функциями-  

 
                