Программирование на C и C++

Онлайн справочник программиста на C и C++

Операторы .* и ->*

Операторы .* и —>* называются операторами-указателями на член. Они позволяют указывать на член класса, а не на конкретный экземпляр члена в каком-то объекте. Эти два оператора нужны постольку, поскольку указатель на член класса не определяет полностью адрес. Вместо этого он обеспечивает смещение до члена в классе. Поскольку указатели на член не являются истинными указателями в полном смысле этого слова, то обычные операторы . и —> не могут использовать­ся. Вместо этого применяются операторы .* и — >*.

Начнем с примера. Следующая программа осуществляет суммирование семи целых чисел. В ней доступ к функции surn_it() и переменной sum осуществляется с использованием указателей на член.

#include <iostream.h>
class myclass {
public:
int sum;
void myclass::sum_it(int x);
};
void myclass::sum_it(int x) {
int i;
sum = 0;
for(i=x; i; i--) sum += i;
}
int main()
{
int myclass::*dp; // указатель на целочисленный член
void (myclass::*fp) (int x); // указатель на функцию-член
myclass с;
dp = &myclass::sum; // получение адреса данных
fp = &myclass::sum_it; // получение адреса функции
(c.*fp)(7); // вычисление суммы с 7
cout << "summation of 7 is " << c.*dp;
return 0;
}

Внутри функции main() программа создает два указателя на член: dp, указывающий на пере­менную sum, и fp, указывающий на функцию sum_it(). Обратим внимание на синтаксис каждого объявления. Для указания класса используется оператор области видимости. В программе также создается объект с класса myclass.

Далее программа получает адреса sum и sum_it(). Как указывалось ранее, эти адреса являются на самом деле смещениями в объекте myclass до членов sum и sum_it(). Далее программа исполь­зует функцию, на которую указывает fp, для вызова функции sum_it() объекта с. Дополнительные скобки необходимы для того, чтобы корректно ассоциировать оператор .*. Наконец, суммарная величина выводится на экран, для чего осуществляется доступ к члену sum объекта с с использо­ванием dp.

При осуществлении доступа к члену объекта с использованием самого объекта или ссылки на него необходимо применять оператор .*. Однако, т. к. используется указатель на объект, то по­требуется оператор —>*, как иллюстрирует следующая версия предыдущей программы:

#include <iostream.h>
class myclass {
public:
int sum;
void myclass::sum_it(int x);
};
void myclass::sum_it(int x) {
int i;
sum = 0;
for(i=x; i; i--) sum += i;
}
int main()
{
int myclass::*dp; // указатель на целочисленный член
void (myclass::*fp) (int x); // указатель на функцию-член
myclass *c, d; // с теперь указатель на объект
с = &d; // с получает адрес объекта
dp = &myclass::sum; // получение адреса данных
fp = &myclass::sum_it; // получение адреса функции
(c->*fp) (7); // использование ->* для вызова функции
cout << "summation of 7 is " << c->*dp; // использование ->*
return 0;
}

В той версии с является указателем на объект типа myclass, а оператор ->* используется для доступа к членам sum и sum_it().