
- •Учебное пособие
- •Введение
- •Объектно-ориентированный подход
- •Объектно-ориентированное программирование Абстрактные типы данных
- •Базовые принципы объектно-ориентированного программирования
- •Простейший ввод и вывод
- •Объект cout
- •Манипуляторы hex и oct
- •Другие манипуляторы
- •Объект cin
- •Операторы для динамического выделения и освобождения памяти (new и delete)
- •Базовые конструкции объектно-ориентированных программ Объекты
- •Понятие класса
- •Конструктор копирования
- •Конструктор explicit
- •Указатели на компоненты класса
- •Встроенные функции (спецификатор inline)
- •Организация внешнего доступа к локальным компонентам класса (спецификатор friend)
- •Вложенные классы
- •Static-члены (данные) класса
- •Указатель this
- •Компоненты-функции static и const
- •Proxi-классы
- •Параметры ссылки
- •Независимые ссылки
- •Практические приемы ограничения числа объектов класса
- •Наследование (производные классы)
- •Конструкторы и деструкторы при наследовании
- •Виртуальные функции
- •Абстрактные классы
- •Виртуальные деструкторы
- •Множественное наследование
- •Виртуальное наследование
- •Перегрузка функций
- •Перегрузка операторов
- •Перегрузка бинарного оператора
- •Перегрузка унарного оператора
- •Дружественная функция operator
- •Перегрузка оператора []
- •Перегрузка оператора ()
- •Перегрузка операторов new и delete
- •Преобразование типа
- •Явные преобразования типов
- •Преобразования типов, определенных в программе
- •Шаблоны Параметризированные классы
- •Передача в шаблон класса дополнительных параметров
- •Шаблоны функций
- •Совместное использование шаблонов и наследования
- •Шаблоны класса и friend
- •Некоторые примеры использования шаблона класса Реализация smart-указателя
- •Классы поддерживающие транзакции
- •Задание значений параметров класса по умолчанию
- •Пространства имен
- •Ключевое слово using как директива
- •Ключевое слово using как объявление
- •Псевдоним пространства имен
- •Организация ввода-вывода
- •Состояние потока
- •Строковые потоки
- •Организация работы с файлами
- •Организация файла последовательного доступа
- •Создание файла произвольного доступа
- •Основные функции классов ios, istream, ostream
- •Основы обработки исключительных ситуаций
- •Перенаправление исключительных ситуаций
- •Исключительная ситуация, генерируемая оператором new
- •Генерация исключений в конструкторах
- •Задание собственной функции завершения
- •Спецификации исключительных ситуаций
- •Задание собственного неожиданного обработчика
- •Иерархия исключений стандартной библиотеки
- •Стандартная библиотека шаблонов (stl) Общее понятие о контейнере
- •Общее понятие об итераторе
- •Категории итераторов
- •Основные итераторы
- •Вспомогательные итераторы
- •Операции с итераторами
- •Контейнерные классы Контейнеры последовательностей
- •Контейнер последовательностей vector
- •Контейнер последовательностей list
- •Контейнер последовательностей deque
- •Ассоциативные контейнеры
- •Ассоциативный контейнер multiset
- •Ассоциативный контейнер set
- •Ассоциативный контейнер multimap
- •Ассоциативный контейнер map
- •Адаптеры контейнеров
- •Адаптеры stack
- •Адаптеры queue
- •Адаптеры priority_queue
- •Пассивные и активные итераторы
- •Алгоритмы
- •Алгоритмы сортировки sort, partial_sort, sort_heap
- •Алгоритмы поиска find, find_if, find_end, binary_search
- •Алгоритмы fill, fill_n, generate и generate_n
- •Алгоритмы equal, mismatch и lexicographical_compare
- •Математические алгоритмы
- •Алгоритмы работы с множествами
- •Алгоритмы swap, iter_swap и swap_ranges
- •Алгоритмы copy, copy_backward, merge, unique и reverse
- •Примеры реализации контейнерных классов Связанные списки
- •Реализация односвязного списка
- •Реализация двусвязного списка
- •Реализация двоичного дерева
- •Литература
- •Вопросы по курсу ооп
- •220013, Минск, п.Бровки, 6.
Наследование (производные классы)
Наследование – это одна из главных особенностей ООП. Наследование заключается в том, что один класс наследует некоторые свойства другого. Этот принцип предполагает использование базового класса, описывающего наиболее общие свойства ряда объектов. Производные классы включают в себя все черты базового класса, а также добавляют новые, характерные только для объектов данного класса. Спецификация описания производного класса имеет следующий синтаксис:
сlass имя_производного_класса : [атрибут] имя_базового_класса
{тело_произв_класса} [список объектов];
Двоеточие отделяет производный класс от базового. Как отмечалось ранее, ключевое слово class может быть заменено на слово struct. При этом все компоненты будут иметь атрибут public. Следует отметить, что объединение (union) не может быть ни базовым, ни производным классом.
Одна из особенностей порожденного класса – видимость унаследованных компонент базового класса. Для определения доступности компонент базового класса из компонент производного класса используются ключевые слова: private, protected и public (атрибуты базового класса). Например:
class base
{ private : private-компоненты;
public : public-компоненты;
protected : protected-компоненты;
};
class proizv_priv : private base { любые компоненты};
class proizv_publ : public base { любые компоненты};
class proizv_prot : protected base { любые компоненты};
Производный класс наследует атрибуты компонент базового класса в зависимости от атрибутов базового класса следующим образом:
если базовый класс имеет атрибут public, то компоненты public и protected базового класса наследуются с атрибутами public и protected в производном классе. Компоненты private остаются private-компонентами базового класса;
если базовый класс имеет атрибут protected, то компоненты public и protected базового класса наследуются с атрибутом protected в производном классе. Компоненты private остаются private-компонентами базового класса;
если базовый класс имеет атрибут private, то компоненты public и protected базового класса наследуются с атрибутами private в производном классе. Компоненты private остаются private-компонентами базового класса.
Отмеченные типы наследования называются: внешним, защищенным и внутренним.
Из этого видно, что использование атрибутов private и protected ограничивает права доступа к компонентам базового класса через производный от базового класс.
Доступ к данным базового класса из производного осуществляется по имени (опуская префикс).
#include <iostream.h>
#include <string.h>
#define n 10
class book // базовый класс book
{ protected:
char naz[20]; // название книги
int kl; // количество страниц
public:
book(char *,int); // конструктор класса book
~book(); // деструктор класса book
};
class avt : public book // производный класс
{ char fm[10]; // фамилия автора
public:
avt(char *,int,char *); // конструктор класса avt
~avt(); // деструктор класса avt
void see();
};
enum razd {teh,hyd,uch};
class rzd : public book // производный класс
{ razd rz; // раздел каталога
public:
rzd(char *, int, razd); // конструктор класса rzd
~rzd(); // деструктор класса rzd
void see();
};
book::book(char *s1,int i) : kl(i)
{ cout << "\n работает конструктор класса book";
strcpy(naz,s1);
}
book::~book()
{cout << "\n работает деструктор класса book";}
avt::avt(char *s1,int i,char *s2) : book(s1,i)
{ cout << "\n работает конструктор класса avt";
strcpy(fm,s2);
}
avt::~avt()
{cout << "\n работает деструктор класса avt";}
void avt::see()
{ cout<<"\nназвание : "<<naz<<"\nстраниц : "<<kl;
}
rzd::rzd(char *s1,int i,razd tp) : book(s1,i), rz(tp)
{ cout << "\n работает конструктор класса rzd";
}
rzd::~rzd()
{cout << "\n работает деструктор класса rzd";}
void rzd::see()
{ switch(rz)
{ case teh : cout << "\nраздел технической литературы"; break;
case hyd : cout << "\ nраздел художественной литературы "; break;
case uch : cout << "\ nраздел учебной литературы "; break;
}
}
void main()
{avt av("Книга 1",123," автор1");//вызов конструкторов классов book и avt
rzd rz("Книга 1",123,teh); //вызов конструкторов классов book и rzd
av.see();
rz.see();
}
На приведенном ниже примере показаны различные способы доступа к компонентам классов иерархической структуры, в которой классы A, B, C - базовые для класса D, а класс D, в свою очередь, является базовым для класса Е.
#include "iostream.h"
class A
{ private: a_1(){cout<<"private-функция a_1"<< endl;}
protected: a_2(){cout<<"protected-функция a_2"<< endl;}
public: a_3(){cout<<"public-функция a_3"<< endl;}
};
class B
{ private: b_1(){cout<<"private-функция b_1"<< endl;}
protected: b_2(){cout<<"protected-функция b_2"<< endl;}
public: b_3(){cout<<"public-функция b_3"<< endl;}
};
class C
{ private: c_1(){cout<<"private-функция c_1"<< endl;}
protected: c_2(){cout<<"protected-функция c_2"<< endl;}
public: c_3(){cout<<"public-функция c_3"<< endl;}
};
class D : public A, protected B, private C
{ private: d_1(){cout<<"private-функция d_1"<< endl;}
protected: d_2(){cout<<"protected-функция d_2"<< endl;}
public: d_3();
};
D:: d_3()
{ d_1();
d_2();
// a_1(); //'a_1' cannot access private member declared in class 'A'
a_2();
a_3();
// b_1(); //'b_1' cannot access private member declared in class 'B'
b_2();
b_3();
// c_1(); //'c_1' cannot access private member declared in class 'C'
c_2();
c_3();
return 0;
}
class E : public D
{ public: e_1();
};
E:: e_1()
{// a_1(); //'a_1' cannot access private member declared in class 'A'
a_2();
a_3();
// b_1(); // b_1 cannot access private member declared in class 'B'
b_2();
b_3();
// c_1(); // c_1 cannot access private member declared in class 'C'
// c_2(); // c_2 cannot access private member declared in class 'C'
// c_3(); // c_3 cannot access private member declared in class 'C'
return 0;
}
int main()
{ A a;
a.a_3();
B b;
b.b_3();
C c;
c.c_3();
D d;
d.a_3();
// d.b_3(); // b_3 cannot access public member declared in class 'B'
// d.c_3(); // c_3 cannot access public member declared in class 'C'
E e;
e.d_3();
e.e_1();
return 0;
}