Указатели на объекты и члены класса

Адрес объекта можно сохранить в указателе. Объявление указателя на объект производится так же как и на любой другой тип данных. Для получения адреса объекта используется оператор &, а для доступа к членам вместо точки применяется оператор ->. Пример использования указателя на объект приведен в листинге 13.20.

Листинг 13.20. Использование указателя на объект

#include <iostream>

class Point {
public:
   int x, y;
   void dump();
};

void Point::dump() { std::cout << x << " " << y << std::endl; }

int main() {
   Point point;        // Объявление объекта
   Point *p = &point;  // Создание указателя на объект
   int *pY = &point.y; // Создание указателя на поле
   p->x = 10;          // Доступ к полю через указатель на объект
   *pY = 20;           // Доступ к полю через указатель на поле
   p->dump();          // Вызов метода через указатель на объект
   return 0;
}

Как видно из примера, сохранить в указателе можно не только адрес объекта, но и адрес общедоступного поля. Помимо указателей на объекты и общедоступные поля язык C++ позволяет создавать указатели на члены класса. Указатель на член класса хранит не адрес члена внутри объекта, а его смещение внутри класса. Объявление указателя на член класса выглядит так:

<Тип> <Название класса>::*<Название указателя>;

После объявления необходимо присвоить указателю смещение определенного поля. Выполняется это следующим образом:

<Название указателя> = &<Название класса>::<Название поля>;

Объявление указателя на метод класса выглядит так:

<Тип> (<Название класса>::*<Название указателя>)([<Тип1>[, ..., 
                                                  <ТипN>]]);

Присвоить указателю смещение метода внутри класса можно так:

<Название указателя> = &<Название класса>::<Название метода>;

Для доступа к члену через объект используется оператор .*, а для доступа через указатель применяется оператор ->*. Пример использования указателей на члены класса приведен в листинге 13.21.

Листинг 13.21. Указатели на члены класса

#include <iostream>

class Point {
public:
   int x, y;
   void dump();
};

void Point::dump() { std::cout << x << " " << y << std::endl; }

int main() {
   Point point;           // Объявление объекта
   Point *p = &point;     // Создание указателя на объект

   int Point::*pX;        // Объявление указателя на член
   pX = &Point::x;        // Получаем смещение поля x
   point.*pX = 10;        // Доступ к полю через объект

   int Point::*pY;        // Объявление указателя на член
   pY = &Point::y;        // Получаем смещение поля y
   p->*pY = 20;           // Доступ к полю через указатель

   void (Point::*func)(); // Объявление указателя на функцию-член
   func = &Point::dump;   // Получаем смещение метода dump()
   (point.*func)();       // Вызов метода через объект
   (p->*func)();          // Вызов метода через указатель

   return 0;
}

Обратите внимание на круглые скобки внутри которых размещается название объекта (или название указателя на объект) и указатель на метод. Эти скобки являются обязательными. Вторые круглые скобки используются для вызова метода.

(point.*func)();          // Эквивалентно point.dump();
(p->*func)();             // Эквивалентно p->dump();

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов