
- •1. Объявление класса. Примеры. Понятие инкапсуляции, полиформизма, наследования.
- •2. Доступ к членам класса. Управление доступом к членам класса. Указатель this. Примеры.
- •3. Конструкторы и деструкторы. Параметризованные конструкторы. Примеры.
- •4. Дружественные ф-ции. Примеры.
- •5. Перегрузка функций. Значение аргументов ф-ции по умолчанию. Примеры.
- •6. Наследование. Примеры.
- •7. Передача объектов в ф-ции и возврат объекта из ф-ции. Массивы объектов. Примеры.
- •8. Перегрузка операторов при помощи функций-членов класса. Примеры.
- •9. Перегрузка операторов при помощи дружественных ф-ций. Примеры.
- •10. Ссылки, ссылки на объекты. Примеры.
- •11. Конструктор копирования. Примеры
- •12. Наследование и спецификаторы доступа. Примеры.
- •13. Конструкторы и деструкторы производных классов. Примеры.
- •14. Указатели и ссылки на производные типы. Примеры.
- •Ссылки на производные классы
- •15. Виртуальные ф-ции. Примеры.
- •16. Чисто виртуальные ф-ции и абстрактные классы. Примеры.
- •17. Обработка исключений. Примеры.
- •18. Создание собственных операторов вставки и извлечения. Примеры.
- •19. Файловый ввод-вывод. Примеры.
- •20. Формирование ввода-вывода. Примеры.
- •21. Двоичные файлы. Примеры.
- •22. Произвольный доступ. Примеры.
- •23. Ввод-вывод в массивы Примеры.
- •24. Класс string. Примеры.
- •25. Функции-шаблоны. Примеры.
- •Явная перегрузка функций-шаблонов
- •26. Классы-шаблоны. Примеры.
- •27. Пространства имён. Примеры.
- •28. Статические члены класса. Примеры.
- •30. Идентификация типа во время исполнения. Примеры.
- •31. Новые операторы приведения типов. Примеры.
- •32. Контейнерные классы. Примеры.
13. Конструкторы и деструкторы производных классов. Примеры.
При наличии и у базового, и у производного классов конструкторов и/или деструкторов, конструкторы выполняются в порядке наследования, а деструкторы - в обратном порядке. То есть, конструктор базового класса выполняется первым, конструктор производного класса - вторым; деструктор производного класса выполняется первым, деструктор базового класса - вторым.
При этом необходимо помнить, что ни конструкторы, ни деструкторы не наследуются (кроме случая виртуальных деструкторов).
Передача аргументов для конструктора производного или базового класса происходит следующим образом. При инициализации только в производном классе, аргументы передаются как обычно. При необходимости передать аргумент конструктору базового класса отрабатывается следующий алгоритм:
1. все необходимые аргументы базового и производного классов передаются конструктору производного класса,
2. используя расширенную форму объявления конструктора производного класса, соответствующие аргументы передаются дальше в базовый класс.
Синтаксис передачи аргументов из производного класса в базовый имеет вид:
конструктор_производного_класса(аргументы) : имя_базового_класса(аргументы)
{ // определение конструктора производного класса
}
Базовый и производный классы могут использовать одни и те же аргументы. Кроме того, производный класс может не использовать полученные аргументы (все или часть), а просто передавать их в базовый класс.
Обычно конструкторы базового и производного классов не используют один и тот же аргумент. Тогда конструктору производного класса передаются все аргументы, необходимые как для производного, так и для базового класса. Затем конструктор производного класса использует свои аргументы, и передает базовому классу аргументы, предназначенные для него. При этом конструктору производного класса нет необходимости использовать аргументы, полученные им для передачи в базовый класс.
14. Указатели и ссылки на производные типы. Примеры.
В общем случае указатель одного типа не может указывать на объект другого типа. Из этого правила, однако, есть исключение, которое относится только к производным классам. В С++ указатель на базовый класс может указывать на объект производного класса, полученного из этого базового класса. Предположим, например, что имеется базовый класс B_class и его производный класс D_class. В С++ любой указатель типа B_class* может также указывать на объект типа D_class. Например, если имеются следующие объявления переменных: B_class *р; // указатель на объект типа B_class B_class B_ob; // объект типа B_class D_class D_ob; // объект типа D_class
то следующие присвоения абсолютно законны: р = &В_оb; // р указывает на объект типа B_class р = &D_ob; /* р указывает на объект типа D_class, являющийся объектом, порожденным от B_class */
Используя указатель р, можно получить доступ ко всем членам D_ob, которые наследованы от B_ob.
Однако специфические члены D_ob не могут быть получены с использованием указателя р (по крайней мере до тех пор, пока не будет осуществлено приведение типов). Это является следствием того, что указатель «знает» только о членах базового типа и не знает ничего о специфических членах производных типов.
Хотя указатель, имеющий тип указателя на базовый класс, может использоваться в качестве указателя на производный объект, обратное не имеет места. Это означает, что указатель, имеющий тип указателя на производный класс, не может использоваться для доступа к объектам базового типа. И еще одно замечание. Инкремент и декремент указателя выполняются по отношению к его базовому типу. Таким образом, если указатель на базовый тип указывает на объект производного класса, инкремент или декремент его не даст указатель на следующий объект производного класса. Поэтому нельзя использовать операции инкремента и декремента указателей, когда они указывают на объект производного класса.