Однако имеется одно отличие в применении указателей на данные-члены и указателей на функции члены. Если необходимо использовать обычный указатель (не на член класса) на данное-член, просто действуйте обычным образом.
int* pi = &obj.ival_;
Конечно, вы используете имя объекта, а не имя класса, потому что получаете адрес конкретного данного-члена конкретного объекта, расположенного где-то в памяти. (Однако обычно стараются адреса данных-членов класса не выдавать за его пределы, чтобы нельзя было их изменить из-за опрометчивых действий в клиентском программном коде.)
В отличие от данного члена с функцией-членом вы не можете сделать то же самое, потому что это бессмысленно. Рассмотрим указатель на функцию, имеющую такую же сигнатуру, как MyClass::incr (т.е. он возвращает void и не имеет аргументов).
void (*pf)();
Теперь попытайтесь присвоить этому указателю адрес функции-члена.
pf = &MyClass::incr; // He получится
pf = &obj.incr;      // И это не пройдет
Обе эти строки не будут откомпилированы, и на это имеются веские основания. Применение функции-члена имеет разумный смысл только в контексте объекта, поскольку, вероятнее всего, она должна ссылаться на переменные-члены. Вызов функции-члена без объекта означало бы невозможность в функции-члене использовать какие-либо члены объекта, а эта функция, по-видимому, как раз является функцией-членом, а не автономной функцией, потому что использует члены объекта.
Рецепт 15.1.
15.3. Обеспечение невозможности модификации аргумента в функции
Вы пишете функцию и требуется гарантировать, что ее аргументы не будут модифицированы при ее вызове.
Для предотвращения изменения аргументов вашей функцией объявите ее аргументы с ключевым словом const. Короткий пример 15.3 показывает, как это можно сделать.
#include <iostream
#include <string>
void concat(const std::string& s1, // Аргументы объявлены как константное,
 const std::string& s2,            // поэтому не могут быть изменены
 std::string& out) {
 out = s1 + s2;
}
int main() {
 std::string s1 = 'Cabo ';
 std::string s2 = 'Wabo';
 std::string s3;
 concat(s1, s2, s3);
 std::cout << 's1 = ' << s1 << '
';
 std::cout << 's2 = ' << s2 << '
';
 std::cout << 's3 = ' << s3 << '
';
}
В примере 15.3 продемонстрировано прямое использование ключевого слова const. Существует две причины объявления параметров вашей функции с этим ключевым словом, когда вы не планируете их изменять. Во-первых, этим вы сообщаете о своих намерениях читателям вашего программного кода. Объявляя параметр как const, вы фактически говорите, что он является concat из примера 15 3.
void concatUnsafe(std::string& s1,
 std::string& s2 std::string& out) {
 out = s1 += s2; // Ну вот, записано значение в s1
}
Несмотря на мою привычку тщательно подходить к кодированию программ, я сделал глупую ошибку и написал += вместо +. В результате при вызове concatUnsafe будут модифицированы аргументы out и s1, что может оказаться сюрпризом для пользователя, который едва ли рассчитывает на модификацию одной из исходных строк.
Спасти может const. Создайте новую функцию concatSafe, объявите переменные константными, как показано в примере 15.3, и функция не будет откомпилирована.
void concatSafe(const std::string& s1,
 const std::string& s2, std::string& out) {
 out = s1 += s2; // Теперь вы получите ошибку компиляции
}
concatSafе гарантирует неизменяемость значений в s1 и s2. Эта функция делает еще кое-что: она позволяет пользователю передавать константные аргументы. Например, программный код, выполняющий конкатенацию строк, мог бы выглядеть следующим образом.
void myFunc(const std::string& s) { // Обратите внимание, что s является
                                    // константной переменной
 std::string dest;
 std::string tmp = 'foo';
 concatUnsafe(s, tmp, dest); // Ошибка: s - константная переменная
                             // Выполнить какие-то действия с dest...
}
В данном случае функция myFunc не будет откомпилирована, потому что concatUnsafe не обеспечивает const'антность myFunc. myFunc гарантирует внешнему миру, что она не будет модифицировать содержимое s, т.е. все действия с s внутри тела myFunc не должны нарушать это обещание. Конечно, вы можете обойти это ограничение, используя оператор const_cast и тем самым освобождаясь от константности, но такой подход ненадежен, и его следует избегать. В этой ситуации concatSafe будет компилироваться и выполняться нормально.
Указатели вносят темные штрихи в розовую картину const. Когда вы объявляете переменную-указатель как параметр, вы имеет дело с двумя объектами: самим адресом и то, на что ссылается этот адрес. C++ позволяет использовать const для ограничения действий по отношению к обоим объектам. Рассмотрим еще одну функцию конкатенации, которая использует указатели.

 
                