- •А. В. Кибардин
- •Оглавление
- •Введение
- •Классы Описание класса
- •Описание объектов
- •Указательthis
- •Конструкторы
- •Конструктор копирования
- •Конструктор копирования для класса monstr:
- •Статические элементы класса
- •Статические поля
- •Статические методы
- •Дружественные функции и классы Дружественные функции
- •Дружественный класс
- •Деструкторы
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Наследование Ключи доступа
- •Простое наследование
- •Правила наследования методов
- •Виртуальные методы и механизм позднего связывания
- •Абстрактные классы
- •Обработка исключительных ситуаций
- •Синтаксис исключений
- •Перехват исключений
- •Список исключений
- •Иерархии исключений
- •Стандартная библиотека
- •Потоковые классы
- •Стандартные потоки
- •Форматирование данных
- •Флаги и форматирующие методы
- •Манипуляторы
- •Методы обмена с потоком
- •Ошибки потоков
- •Файловые потоки
- •Строковые потоки
- •Конструкторы и присваивание строк
- •Операции
- •Функции Присваивание и добавление частей строк
- •Преобразование строк
- •Поиск подстрок
- •Сравнение частей строк
- •Получение характеристик строк
- •Контейнерные классы
- •Последовательные контейнеры
- •Векторы
- •Двусторонние очереди
- •Ассоциативные контейнеры
- •Словари
- •Словари с дубликатами (multimap)
- •Приложение 1. Шаблоны функций
- •Приложение 2. Шаблоны классов
- •Библиографический список
- •В трех частях
Дружественный класс
Если все методы какого-либо класса должны иметь доступ к скрытым полям другого, весь класс объявляется дружественным с помощью ключевого слова friend.
class hero {
…
friend class mistress;
};
class mistress {
…
void f1 ( );
void f2 ( );
};
Функции f1 и f2 являются дружественными по отношению к классу hero.
!!! Объявление friend не является спецификатором доступа и не наследуется.
Деструкторы
Деструкторы – это особый вид метода, применяющийся для освобождения памяти, занимаемой объектом. Деструктор вызывается автоматически, когда объект выходит из области видимости:
– для локальных объектов – при выходе из блока, в котором они объявлены;
– для глобальных объектов – как часть процедуры выхода из main;
– для объектов, заданных через указатели, деструктор вызывается неявно при использовании операции delete.
Имя деструктора начинается с тильды (~), непосредственно за которой следует имя класса. Деструктор:
– не имеет аргументов и возвращаемого значения;
– не может быть объявлен как const или static;
– не наследуется;
– может быть виртуальным.
Если деструктор явно не определен, компилятор автоматически создает пустой деструктор.
Описывать явно деструктор требуется, когда объект содержит указатели на память, выделяемую автоматически.
Пример. Модифицированная структура monstr с полем name (см. ранее).
monstr:: ~ monstr ( ) {delete [ ] name;}
Деструктор можно вызвать явным образом путем указания полностью уточненного имени, например:
monstr *m; …
m -> ~ monstr ( );
Задание
Добавьте в описание созданного вами класса деструктор.
Перегрузка операций
С++ позволяет переопределять действия большинства операций так, чтобы при использовании их с объектами конкретного класса они выполняли заданные функции. Это дает возможность использовать собственные типы данных как стандартные. Обозначения собственных операций вводить нельзя. Можно перегружать любые операции, за исключением:
. .* ?: :: # ## sizeof
Перегрузка операций осуществляется с помощью методов специального вида (функций-операций) и подчиняется следующим правилам:
– при перегрузке операций сохраняются количество аргументов, приоритеты операций и правила ассоциации (справа налево или слева направо), используемые в стандартных типах данных;
– для стандартных типов данных переопределять операции нельзя;
– функции-операции не могут иметь аргументов по умолчанию;
– функции-операции наследуются (за исключением =);
– функции-операции не могут определяться как static.
Функцию-операцию можно определить тремя способами: она должна быть либо методом класса, либо дружественной дружественной функцией класса, либо обычной функцией. В двух последних случаях функция должна принимать хотя бы один аргумент, имеющий тип класса, указателя или ссылки на класс.
Функция-операция содержит ключевое слово operator, за которым следует знак переопределяемой операции:
Тип operator (список параметров) {тело функции}
Перегрузка унарных операций
Унарная функция-операция, определяемая внутри класса, должна быть представлена с помощью нестатического метода без параметров, при этом операндом является вызвавший ее объект, например:
class monstr {
…
monstr & operator ++ ( ) {++ health; return *this;}
};
monstr Vasia;
cout << (++Vasia).get_health ( );
Если функция определяется вне класса, она должна иметь один параметр типа класса:
class monstr {
…
friend monstr & operator ++ (monstr &M);
};
monstr &operator ++ (monstr &M) {++ M.health; return M;}
Если не описывать функцию внутри класса как дружественную, нужно учитывать доступность изменяемых полей. В данном случае поле health недоступно вызовам извне, так как описано со спецификатором private, поэтому для его изменения требуется использование соответствующего метода. Введем в описание класса monstr метод change_health, позволяющий изменить значение поля health:
void change_health (in the) {health=he;}
Тогда можно перегрузить операцию инкремента с помощью обычной функции, описанной вне класса:
monstr &operator ++ (monstr &M) {
int h=M.get_health ( ); h++;
M.change_health (h);
return M;
}
Операции постфиксного инкремента и декремента должны иметь первый параметр типа int. Он используется только для того, чтобы отличить их от префиксной формы:
class monstr {
…
monstr operator ++ (int) {
monstr M(*this); health ++;
return M;
}
};
monstr Vasia;
cout <<(Vasia++).get_health ( );