- •А. В. Кибардин
- •Оглавление
- •Введение
- •Классы Описание класса
- •Описание объектов
- •Указательthis
- •Конструкторы
- •Конструктор копирования
- •Конструктор копирования для класса monstr:
- •Статические элементы класса
- •Статические поля
- •Статические методы
- •Дружественные функции и классы Дружественные функции
- •Дружественный класс
- •Деструкторы
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Наследование Ключи доступа
- •Простое наследование
- •Правила наследования методов
- •Виртуальные методы и механизм позднего связывания
- •Абстрактные классы
- •Обработка исключительных ситуаций
- •Синтаксис исключений
- •Перехват исключений
- •Список исключений
- •Иерархии исключений
- •Стандартная библиотека
- •Потоковые классы
- •Стандартные потоки
- •Форматирование данных
- •Флаги и форматирующие методы
- •Манипуляторы
- •Методы обмена с потоком
- •Ошибки потоков
- •Файловые потоки
- •Строковые потоки
- •Конструкторы и присваивание строк
- •Операции
- •Функции Присваивание и добавление частей строк
- •Преобразование строк
- •Поиск подстрок
- •Сравнение частей строк
- •Получение характеристик строк
- •Контейнерные классы
- •Последовательные контейнеры
- •Векторы
- •Двусторонние очереди
- •Ассоциативные контейнеры
- •Словари
- •Словари с дубликатами (multimap)
- •Приложение 1. Шаблоны функций
- •Приложение 2. Шаблоны классов
- •Библиографический список
- •В трех частях
Простое наследование
Простым называется наследование, при котором производный класс имеет одного родителя. Для различных методов класса существуют разные правила наследования – например, конструкторы и операция присваивания в производном классе не наследуются, а деструкторы наследуются.
Пример. Описание класса daemon, производного от класса monstr:
enum color {red, green, blue};
// monstr
class monstr {
//
int health, ammo;
color skin;
char * name;
public:
//
monstr (int he=100, int am=10);
monstr (color sk);
monstr (char *nam);
monstr (monstr &M);
//
~ monstr ( ) {delete [ ] name;}
//
monstr & operator ++ ( ) {
++ health; return *this;
}
monstr operator ++ (int) {
monstr M (*this);
health ++; return M;
}
operator int ( )
return health;
}
bool operator > (monstr &M) {
if (health > M.get_heath ( )) return true;
return false;
}
const monstr & operator = (monsr &M) {
if (&M == this) return *this;
if (name) delete [ ] name;
if (M.name) {
namt = new char [strlen(M.name)+1];
strcpy (name, M.name); }
else name = 0;
health =M.health; ammj=M.ammo; skin =M.skin;
return *this;
}
//
int get_health ( ) const {return health;}
int get_ammo ( ) const { return ammo;}
//
void change_health (int he) {healt=he;}
//
void draw (int x, int y, int scale, int position);
//
monstr :: monstr (int he, int am):
health (he), ammo (am), skin (red), name (0) { }
monstr :: monstr (monstr &M) {
if (M.name) {
name = new char [strlen(M.name)+1];
strcpy (name, M.name;}
else name = 0;
health =M.health; ammo=M.ammo; skin = M.skin;
}
monstr :: monstr (color sk) {
switch (sk) {
case red: health =100; ammo=10; skin = red;
name=0; break;
case green: health =100; ammo=20, skin=green;
name=0; break;
case blue: health =100; ammo=40; skin=blue;
name=0; break;
}
}
monstr :: monstr (char * nam) {
name = new char [strlen(nam)+1];
strcpy(name, nam);
health =100; ammo =10; skin = red;
}
void monstr :: draw (int x, int y, int scale, int position)
{/**/}
//
class daemon : public monstr {
int brain;
public:
//
daemon (int br=10) {brain = br;}
daemon (color sk) : monstr (sk) {brain = 10;}
daemon (char *nam) : monstr (nam) {brain = 10;}
daemon (daemon &M) : monstr (M) {brain = M.brain;}
//
const daemon &operator = (daemon &M) {
if (&M == this) return *this;
brain = M.brain;
monstr :: operator =(M);
return *this;
}
//
void think ( );
//
void draw (int x, int y, int scale, int position);
}
//
void daemon :: think ( ) {/* */}
void daemon :: draw (int x, int y, int scale, int position) {/* */}
!!! В классе daemon введено поле brain и метод think, определены собственные конструкторы и операция присваивания, а также переопределен метод draw. Все поля класса monstr, операции (кроме присваивания) и методы get_health, get_ammo и change_health наследуются в классе daemon, а деструктор формируется по умолчанию.
Правила наследования методов
Конструкторы не наследуются, поэтому производный класс должен иметь собственные конструкторы. Порядок вызова конструкторов определяется следующими правилами:
– если в конструкторе производного класса явный вызов конструктора базового класса отсутствует, автоматически вызывается конструктор базового класса по умолчанию (т. е. тот, который можно вызвать по умолчанию; пример – первый из конструкторов класса daemon);
– для иерархии, состоящей из нескольких уровней, конструкторы базовых классов вызываются, начиная с самого верхнего уровня. После этого выполняются конструкторы тех элементов класса, которые являются объектами, в порядке их объявления в классе, а затем исполняется конструктор класса;
– в случае нескольких базовых классов их конструкторы вызываются в порядке объявления.
Не наследуется операция присваивания, поэтому ее следует также явно определить в производном классе.
Для деструкторов существуют следующие правила наследования:
– деструкторы не наследуются, и если программист не описал в производном классе деструктор, он формируется по умолчанию и вызывает деструкторы всех базовых классов;
– в отличие от конструкторов при написании деструкторов производного класса в нем не требуется явно вызывать деструкторы базовых классов;
– для иерархии классов, состоящей из нескольких уровней, деструкторы вызываются в порядке, строго обратном вызову конструкторов: сначала вызывается деструктор класса, затем деструкторы элементов класса, затем деструктор базового класса.
Поля, унаследованные из класса monstr, недоступны функциям производного класса, поскольку они определены в базовом классе как private. Если функциям, определенным в daemon, требуется работать с этими полями, можно либо описать их в базовом классе как protected, либо обращаться к ним с помощью функций из monstr, либо явно переопределить их в daemon.
В классе daemon описан метод draw, переопределяющий метод с тем же именем в классе monstr. Доступ к переопределяющему методу базового класса для производного класса выполняется через имя, уточненное с помощью операции доступа к области видимости (::).
Задание
Образуйте производный класс от созданного вами класса, который в дополнение к родительским методам может вычислять тригонометрические функции, степенную функцию (степень – вещественное число), экспоненциальную функцию и десятичный логарифм.