- •3. Указатели и ссылки. Указатель this.
- •4. Использование операторов new и delete.
- •5. Понятие классов и экземпляров классов.
- •6. Описание классов(class, struct, union).
- •7. Вложенные классы.
- •8. Определение объектов при помощи классов.
- •9. Конструкторы и деструкторы классов.
- •10. Атрибуты доступа к компонентам классов.
- •12. Вызов членов класса.
- •11. Объявление и определение методов класса.
- •13. Перегрузка конструкторов. Конструкторы копий.
- •14. Перегрузка операторов отношения.
- •15. Перегрузка логических операторов.
- •16. Перегрузка унарных операторов.
- •17. Перегрузка бинарных операторов.
- •18. Функция оператор как член класса и как friend функция.
- •19. Дружественные функции.
- •20. Доступ к компонентам классов в зависимости от атрибутов доступа.
- •21. Введение в наследование. Базовые классы.
- •22. Производные классы.
- •23. Ограничение доступа к элементам класса. Наследование свойств и модификаторы доступа. Одиночное наследование. Доступ к компонентам производных и базовых классов.
- •24. Конструкторы базовых и производных классов.
- •25. Виртуальные базовые классы. Чисто виртуальные функции.
- •26. Использование указателей на базовые классы и производные классы. Виртуальные методы.
- •27. Потоки ввода-вывода.
- •28. Иерархия классов ввода-вывода. Основные уровни иерархии. Классы потоков.
- •29. Стандартные классы, объекты и механизмы консольного ввода/вывода.
- •30. Стандартные классы, объекты и механизмы файлового ввода/вывода.
- •31. Понятие манипулятора. Реализация пользовательских манипуляторов.
- •32. Файлы последовательного доступа и произвольного доступа.
- •33. Понятие шаблона. Шаблоны функций и классов.
24. Конструкторы базовых и производных классов.
Некоторые производные классы нуждаются в конструкторах. Если базовый класс имеет конструктор, он должен быть вызван, и если этот конструктор имеет аргументы, они должны быть предоставлены. Аргументы конструктора базового класса указываются в определении конструктора производного класса. В этом отношении базовый класс ведет себя как член производного класса. Конструктор производного класса может указывать инициализаторы для своих собственных членов и членов базового класса; он может непосредственного инициализировать члены базового класса. Объекты класса создаются снизу-вверх: сначала базовый класс, потом члены и затем сам производный класс. Уничтожаются в противоположном направлении.
25. Виртуальные базовые классы. Чисто виртуальные функции.
У базовых классов некоторого производного класса может быть общий предок, что надо учитывать/. Виртуальное наследование общему предку для базовых классов позволяет избежать дублирование свойств общего предка в производном классе Использование вспомогательных методов в базовых классах позволяет избежать повторного вызова методов общего предка в методах производного класса Компилятор позволяет избежать дублирование вызова конструктора общего предка при создании объекта производного класса Конструктор производного класса должен задавать параметры конструкторов базовых классов и конструктора общего виртуального предка.
Виртуальные функции решают проблему, связанную с полем типа, предоставляя возможность программисту объявить в базовом классе функции, которые можно заместить в каждом производном классе. Компилятор и загрузчик гарантируют правильное соответствие между объектами и функциями, примееяемыми к ним. Для того чтобы объявление виртуальной функции работало в качестве интерфейса к функциям, определенным в производных классах, типы аргументов функции в производном классе не должны отличатсья от типов аргументов, объявленных в базовом классе, и только очень небольшие изменения допускаются дял типа возвращаемого значения. Виртуальная функция должна быть определена для класса , в котором она впервые объявлена. Вирт фукнцию можно использовать даже если у ее класса нет производных классов. Производный класс который не нуждается в собственной версии виртуальной функции не обязан ее реализовывать.
26. Использование указателей на базовые классы и производные классы. Виртуальные методы.
class Item
{
public:
. . .
virtual String Name() const = 0;
};
Теперь мы определили метод Name как чисто виртуальный. Класс, у которого есть хотя бы один чисто виртуальный метод, называется абстрактным.
Если метод объявлен чисто виртуальным, значит, он должен быть определен во всех классах, производных от Item. Наличие чисто виртуального метода запрещает создание объекта типа Item. В программе можно использовать указатели или ссылки на тип Item. Записи
Item it;
Item* itptr = new Item;
не разрешены, и компилятор сообщит об ошибке. Однако можно записать:
Book b;
Item* itptr = &b;
Item& itref = b;
Отметим, что, определив чисто виртуальный метод в классе Book, в следующем уровне наследования его уже не обязательно переопределять
class Item
{
public:
virtual String Name(void) const;
. . .
};
class Book : public Item
{
public:
virtual String Name(void) const;
. . .
};
class Magazine : public Item
{
public:
virtual String Name(void) const;
. . .
};
Реализация метода Name для базового класса тривиальна: поскольку название известно только производному классу, мы будем возвращать пустую строку.
String
Item::Name(void) const
{
return "";
}
Для книги название состоит из фамилии автора, названия книги, издательства и года издания:
String
Book::Name(void) const
{
return author + title + publisher +
String(year);
}
У журнала полное название состоит из названия журнала, года и номера:
String
Magazine::Name(void) const
{
return title + String(year) +
String(number);
}
Методы Name определены как виртуальные с помощью описателя virtual, стоящего перед определением метода. Виртуальные методы реализуют идею полиморфизма в языке Си++. Если в программе используется указатель на базовый класс Item и с его помощью вызывается метод Name:
Item* ptr;
. . .
String name = ptr->Name();
то по виду вызова метода невозможно определить, какая из трех приведенных выше реализаций Name будет выполнена. Все зависит от того, на какой конкретный объект указывает указатель ptr.
Item* ptr;
. . .
if (type == "Book")
ptr = new Book;
else if (type == "Magazine")
ptr = new Magazine;
. . .
String name = ptr->Name();
В данном фрагменте программы, если переменная type, обозначающая тип библиотечной единицы, была равна "Book", то будет вызван метод Name класса Book. Если же она была равна "Magazine", то будет вызван метод класса Magazine.
