Выбрать главу

#include <iostream>

using namespace std;

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; // указатель на int-член класса

 void (myclass::*fp)(int x); // указатель на функцию-член

 myclass с;

 dp = &myclass::sum; // получаем адрес члена данных

 fp = &myclass::sum_it; // получаем адрес функции-члена

 (c.*fp)(7); // вычисляем сумму чисел от 1 до 7

 cout << "Сумма чисел от 1 до 7 равна " << с.*dp;

 return 0;

}

Результат выполнения этой программы таков.

Сумма чисел от 1 до 7 равна 28

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

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

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

#include <iostream>

using namespace std;

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; // указатель на int-член класса

 void (myclass::*fp)(int x); // указатель на функцию-член

 myclass *c, d; // член с сейчас -- указатель на объект

 с = &d; // присваиваем указателю с адрес объекта

 dp = &myclass::sum; // получаем адрес члена данных sum

 fp = &myclass::sum_it; // получаем адрес функции sum_it()

 (c->*fp) (7); // Теперь используем оператор для вызова функции sum_it().

 cout << "Сумма чисел от 1 до 7 равна " << c->*dp; // ->*

 return 0;

}

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

Помните, что операторы указания на члены класса предназначены для специальных случаев, и их не стоит использовать для решения обычных повседневных задач программирования.

Создание функций преобразования

Функция преобразования автоматически преобразует тип класса в другой тип.

Иногда возникает необходимость в одном выражении объединить созданный программистом класс с данными других типов. Несмотря на то что перегруженные операторные функции могут обеспечить использование смешанных типов данных, в некоторых случаях все же можно обойтись простым преобразованием типов. И тогда, чтобы преобразовать класс в тип, совместимый с типом остальной части выражения, можно использовать функцию преобразования типа. Общий формат функции преобразования типа имеет следующий вид.