
- •Учебное пособие
- •Введение
- •Объектно-ориентированный подход
- •Объектно-ориентированное программирование Абстрактные типы данных
- •Базовые принципы объектно-ориентированного программирования
- •Простейший ввод и вывод
- •Объект 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.
Виртуальное наследование
Если базовый класс (в приведенном выше примере это класс А) является виртуальным, то будет построен единственный объект этого класса (см. рис. 2).
#include ”iostream.h”
class A // базовый виртуальный класс
{ int aa;
public:
A() {cout<<"Конструктор1 класса A"<<endl;}
A(int AA) : aa(AA) {cout<<"Конструктор2 класса A"<<endl;}
~A() {cout<<"Деструктор класса A"<<endl;}
};
class B : virtual public A // производный класс (1 Базовый)
{ char bb;
public:
B() {cout<<"Конструктор1 класса B"<<endl;}
B(int AA,char BB): A(AA), bb(BB)
{cout<<"Конструктор2 класса B"<<endl;}
~B() {cout<<"Деструктор класса B"<<endl;}
};
class C : virtual public A // производный класс (2 Базовый)
{ float cc;
public:
C() {cout<<"Конструктор1 класса C"<<endl;}
C(int AA,float CC) : A(AA), cc(CC)
{cout<<"Конструктор2 класса C"<<endl;}
~C() {cout<<"Деструктор класса C"<<endl;}
};
class D : public C,public B // производный класс (2 Базовый II уровня)
{ int dd;
public:
D() {cout<<"Конструктор 1 класса D"<<endl;}
D(int AA,char BB,float CC,int DD) :
A(AA), B(AA,BB), C(AA,CC), dd(DD)
{cout<<"Конструктор 2 класса D"<<endl;}
~D() {cout<<"Деструктор класса D"<<endl;}
};
void main()
{ D d(1,'a',2.3,4);
D dd;
}
Результат работы программы:
Конструктор 2 класса A (конструкторы для объекта d)
Конструктор 2 класса C
Конструктор 2 класса B
Конструктор 2 класса D
Конструктор 1 класса A (конструкторы для объекта dd)
Конструктор 1 класса C
Конструктор 1 класса B
Конструктор 1 класса D
Деструктор класса D (деструкторы для объекта d)
Деструктор класса B
Деструктор класса C
Деструктор класса A
Деструктор класса D (деструкторы для объекта d)
Деструктор класса B
Деструктор класса C
Деструктор класса A
Виртуальный базовый класс всегда инициализируется только один раз. В примере при создании объектов d и dd конструктор класса А вызывается из конструктора класса D первым и только один раз, затем - конструкторы классов B и C, в том порядке, в котором они описаны в строке наследования классов:
class D : public B, public C .
В одно и то же время класс может иметь виртуальный и невиртуальный базовые классы, например:
class A{ … };
class B1: virtual public A{ … };
class B2: virtual public A{ … };
class B3: public A{ … };
class C: public B1, public B2, public B3 { … };
В этом случае класс С имеет два подобъекта класса А, один наследуемый через классы В1 и В2 (общий для этих классов) и второй через класс В3
(рис.5, 6).
#include
"iostream.h"
#include "string.h"
class A // базовый класс I уровня
{ char *naz; // название фирмы
public:
A(char *NAZ)
{ naz=new char[strlen(NAZ)+1];
strcpy(naz,NAZ);
}
~A()
{ delete naz;
cout << "деструктор класса А" << endl;
}
void a_prnt(){cout <<"марка а/м "<< naz << endl;}
};
class B1 : virtual public A // производный класс (1 Базовый II уровня)
{ protected:
char *cv; // цвет а/м
int kol; // количество дверей
public:
B1(char *NAZ,char *CV,int KOL): A(NAZ),kol(KOL)
{ cv=new char[strlen(CV)+1];
strcpy(cv,CV);
}
~B1()
{ delete cv; ;
cout << "деструктор класса В1" << endl;
}
void b1_prnt()
{ A::a_prnt();
cout << "цвет а/м" << cv <<" кол-во дверей " << kol <<endl;
}
};
class B2 : virtual public A // производный класс (2 Базовый II уровня)
{ protected:
int pow; // мощность а/м
double rs; // расход топлива
public:
B2(char *NAZ,int POW,double RS): A(NAZ),pow(POW),rs(RS) {};
~B2(){cout << "деструктор класса В2" << endl;}
void b2_prnt()
{ A::a_prnt();
cout <<"мощность двигателя "<<pow<<" расход топлива "<<rs;
cout<<endl;
}
};
class C : public B1,public B2 //производный класс (2 Базовый II уровня)
{ char *mag; // название магазина
public: C(char *NAZ,char *CV,int KOL,int POW,double RS,char *MAG):
B1(NAZ,CV,KOL),B2(NAZ,POW,RS),A(NAZ)
{ mag =new char[strlen(MAG)];
strcpy(mag,MAG);
}
~C()
{ delete mag;
cout << "деструктор класса С" << endl;
}
void c_prnt()
{ A::a_prnt();
B1::b1_prnt();
B2::b2_prnt();
cout << " название магазина" << mag <<endl;
}
};
void main()
{ C cc("BMW","красный",100,4,8.5,"магазин 1"),*pt=&cc;
cc.a_prnt();
pt->a_prnt();
cc.b1_prnt();
pt->b1_prnt();
cc.b2_prnt();
pt->b2_prnt();
cc.c_prnt();
pt->c_prnt();
}