
- •1. Введение
- •2. Элементы языка
- •2.1. Первые программы
- •2.2. Алфавит языка
- •2.3. Комментарии
- •2.4. Типы данных
- •2.5. Целые типы данных
- •2.6. Плавающие типы данных
- •2.7. Константы-строки, или литералы
- •2.8. Директива препроцессора define
- •2.9. Описания
- •2.10. Модификатор const
- •3. Выражения
- •3.1. Операция и выражение присваивания
- •3.2. Арифметические операции
- •3.3. Операции отношения
- •3.4. Логические операции
- •3.5. Побитовые операции
- •3.6. Сдвиги
- •?????3.8. Тернарная или условная операция
- •3.9. Операция следования
- •3.10. Приоритеты операций и порядок вычисления
- •4.6. Оператор выбора switch
- •4.7. Оператор цикла while
- •4.8. Цикл с постусловием do-while
- •4.9. Оператор for
- •4.10. Оператор безусловного перехода
- •4.11. Оператор break
- •4.12. Оператор continue
- •4.13. Оператор return
- •5. Указатели
- •5.1. Определение указателей
- •5.2. Указатели и массивы
- •5.3. Адресная арифметика
- •5.4. Символьные массивы и строки
- •5.5. Многомерные массивы
- •5.6. Указатели и многомерные массивы
- •6. Операция sizeof
- •7. Операции для работы с динамической памятью
- •7.1. Операция выделения памяти new
- •7.2. Операция освобождения памяти delete
- •8. Функции
- •8.1. Определение и вызов функции
- •8.2. Функции. Передача аргументов
- •8.3. Передача многомерных массивов
- •8.4. Указатели на функции
- •8.5. Ссылки
- •8.6. Ссылки в качестве параметров функций
- •8.7. Аргументы по умолчанию
- •8.8. Переопределение функций
- •8.9. Шаблоны функций
- •9. Объявления и определения
- •10. Область существования имени
- •11. Область видимости
- •Здесь будет напечатано
- •12. Классы памяти
- •13. Объявления объектов и типов
- •14. Имена типов
- •15. Синоним имени типа
- •16. Правила преобразования стандартных типов
- •16.1. Явные преобразования
- •16.2. Неявные преобразования стандартных базовых типов
- •16.3. Преобразование производных стандартных типов
- •17. Перечисления
- •18. Классы
- •18.1. Объявление классов
- •18.2. Конструкторы
- •18.3. Деструкторы
- •18.4. Статические члены класса
- •18.5. Указатель this
- •18.6. Статические функции-члены
- •18.7. Указатели на члены класса
- •18.8. Инициализация данных–членов класса
- •18.9. Конструктор копирования и операция присваивания
- •18.10. Дружественные функции
- •18.11. Конструктор и операция new
- •18.12. Вызов деструктора
- •19. Производные классы
- •19.1. Построение производного класса
- •19.2. Защищенные члены класса
- •19.3. Управление уровнем доступа к членам класса
- •19.4. Последовательность вызова конструктора и деструктора при построении производного класса на основе одного базового
- •19.5. Преобразования типов
- •20. Полиморфизм
- •20.1. Раннее и позднее связывание
- •20.2. Виртуальные функции
- •20.3. Абстрактные классы
- •21. Переопределение стандартных операций
- •21.1. Основные определения и свойства
- •21.2. Операции new и delete при работе с абстрактными типами
- •21.3. Использование new при создании динамического объекта абстрактного типа
- •21.4. Операция delete
- •21.5. Преобразование типов
- •22. Некоторые особенности переопределенных операций
- •22.2. Операция [ ]
- •23. Классы и шаблоны
- •24. Списки
- •24.1. Операции над односвязными списками
- •24.2. Двунаправленные и кольцевые списки
- •24.3. Операции над кольцевыми списками
- •25. Стеки
- •25.1. Реализация стека через массив
- •25.2. Реализация стека через динамическую цепочку звеньев
- •26. Двоичные деревья
- •26.1. Определение и построение
- •26.2.Таблицы
- •27. Список литературы
18.7. Указатели на члены класса
Для членов класса (кроме битовых полей) определена операция получения адреса. Указатели на данные-члены класса никаких особенностей не имеют. Особенностью указателя на функцию-член класса является явное присутствие в его объявлении имени класса, за которым следует ::.
class cl {. . .
public:
int f (char*, int);
void g();
. . .
};
/* Как и для указателя на обычную функцию, при объявлении указателя на компонентную функцию необходимо объявить типы результата и аргументов функции, на которую заводиться указатель. Как обычно, указатель можно инициализировать при объявлении: */
int (cl ::*fptr) (char *, int) = cl::f;
Пример:
struct s {int mem;
s (int a){mem=a;}
void func(int a){cout<<a+mem<<’\n’;}
};
void main(){
void (s::*fp)(int) = s::func;
s obj(5);
s *p = &obj;
// Два варианта вызова функции-члена по указателю -
(obj.*fp)(6); // используя объект obj типа s
(p->*fp)(9); // и указатель p на него.
}
Здесь .* (как и ->*) являются символами одной – единственной операци, а не находящимися рядом символами двух ранее знакомых нам операций ‘.’ (‘->’) и *. Правым операндом операций .* и ->* обязательно должен быть указатель на член класса, а не любой указатель.
18.8. Инициализация данных–членов класса
Инициализация членов абстрактных типов
Пусть класс содержит в себе члены абстрактных типов. Особенностью их инициализации является то, что она выполняется с помощью соответствующего конструктора. Рассмотрим класс
class coord {double x, y, z;
public:
coord (){x = y = z =0;}
coord (double xv, double yv, double zv=0) { x = xv; y = yv; z = zv;}
coord (coord & c){x = c.x; y = c.y; z = c.z;}
};
class triang{
coord vert1, vert2, vert3; // Координаты вершин треугольника.
public:
triang ();
triang (coord &v1, coord &v2, coord &v3);
};
При инициализации некоторого объекта класса triang потребуется три раза вызвать конструкторы для его вершин - объектов типа coord. Для этого в определении конструктора класса triang после двоеточия нужно поместить список обращений к конструкторам класса coord:
Traing::triang (coord &v1, coord &v2, coord &v3):
vert1 (v1), vert2 (v2), vert3 (v3){. . .}
Вызов конструкторов класса coord происходит до выполнения тела самого конструктора класса triang. Порядок их вызова определяется порядком появления объявлений членов типа coord при создании класса triang.
Класс coord содержит конструктор без аргументов. Вместо записи при обращении к такому конструктору
triang::triang (): vert1(), vert2(), vert3() {. . .}
допускается написать просто так:
triang::triang (){. . .}
Инициализация констант
Если среди данных-членов класса имеются члены, описанные с модификатором const, то при инициализации используется та же форма записи конструктора, что и в случае с данными абстрактных типов:
class cl{ int v;
const c;
public:
cl (int a, int b):c (b) {v=a;}
};
Константу можно инициализировать только в конструкторе, попытка сделать это любым другим способом (например, с помощью другой компонентной функции) приведет к сообщению об ошибке. Инициализация констант в теле конструктора тоже недопустима.
Замети, что способ записи конструктора, обязательный для констант и данных абстрактных типов, можно использовать и для обычных членов класса:
class ro{ int var; const c;
public:
ro (int v, int u): c(u), var (v) {}
};