
- •5.Препроцессор. Директивы препроцессора.
- •7.Работа с файлами. Текстовый и двоичный режим.
- •8.Указатели. Адресная арифметика.
- •10.Перечислимый тип. Структуры. Объединения.
- •11.Поразрядные операции.
- •13.Спецификаторы класса памяти.
- •14.Пространства имён.
- •15.Компоновка. Правило одного определения.
- •16.Понятие класса.
- •17.Функции-члены класса. Указатель this.
- •18.Конструкторы. Деструкторы.
- •19.Преобразования объектов класса.
- •20.Доступ к членам класса.
- •21.Статические члены класса.
- •22.Друзья класса.
- •23.Совместное использование.
- •24.Перегрузка операций.
- •25.Шаблоны.
- •26.Обработка исключительных ситуаций.
- •27.Производные классы.
- •28.Виртуальные функции. Абстрактные классы.
- •29.Указатели на члены класса.
- •30.Множественное наследование.
- •31.Структура dll-библиотеки.
- •32.Статическое и динамическое подключение dll-библиотек.
- •34.Регистры процессора.
- •35.Использование стека. Команды работы со стеком в языке ассемблера.
- •36.Арифметические команды в языке ассемблера.
- •37.Команды сравнения и перехода в языке ассемблера.
- •38.Команды работы с битами в языке ассемблера.
- •39.Процедуры в языке ассемблера. Передача параметров в процедуру.
- •40.Процедуры в языке ассемблера. Возврат результата. Локальные данные.
27.Производные классы.
Рассмотрим приведённый во введении пример. И круг, и треугольник являются фигурами, однако если не использовать специальных средств для явного указания этого факта, компилятор сам не сможет сделать подобный вывод. Соответственно, мы не сможем, например, поместить указатели на объекты классов Circle иTriangle в один список. Такое отношение между классами называют наследованием.
Класс может быть порождён из другого класса, который называется базовым классом производного класса. Класс может быть порождён из одного или нескольких классов. Порождённые классы наследуют свойства базовых классов, включая данные-члены и функции-члены. Кроме того, в производном классе могут быть объявлены дополнительные данные-члены и функции-члены.Объявление производного класса имеет следующий синтаксис: class <имя производного класса> : <спецификатор доступа> <имя базового класса> [, <спецификатор доступа> <имя базового класса> ]
{ ... };
Отношение
наследования между классами может быть
представлено в графическом виде.
Популярной и эффективной реализацией понятия производных классов является представление объекта производного класса в виде объекта базового класса и информации, относящейся только к производному классу.
П
роизводный
класс может сам, в свою очередь, служить
базовым классом.
Если члены базового класса не переопределены в производном классе, они обозначаются и трактуются так же, как и члены производного класса. Говорят, что члены базового класса наследуются производным классом. Операция разрешения области видимости :: может употребляться для явной ссылки на член базового класса. Это обеспечивает доступ к имени, которое переопределено в производном классе.
Возвращаясь к рассматриваемому примеру, мы видим, что круг является фигурой. Поэтому Circle* можно использовать как Shape*. Однако фигура не обязательно является кругом, поэтому Shape* нельзя использовать как Circle*. В общем случае, указатель на производный класс может быть неявно преобразован к указателю на однозначно доступный базовый класс. Ссылка на производный класс может быть неявно преобразована к ссылке на однозначно доступный базовый класс.
class Base { public: int a, b; }; class Derived : public Base { public: int b, c; }; Derived d; |
|
d.a = 1; d.Base::b = 2; d.b = 3; d.c = 4; Base *bp = &d; |
// Инициализация a, унаследованного из класса Base // Инициализация b из класса Base // Инициализация b, объявленного в классе Derived
// Преобразуем указатель на класс Derived в указатель на класс Base |
Класс называется непосредственным базовым классом, если он упоминается при объявлении производного класса, и косвенным базовым классом, если он является базовым классом для одного из базовых классов объявляемого класса.
class A { public: void f(); }; class B : public A { }; class C : public B { public: void f(); void ff(); }; |
// Класс B является непосредственным базовым классом для класса C, // а класс A – косвенным базовым классом для класса C |
В записи <имя класса>::<имя> имя класса может быть именем косвенного базового класса, это имя класса определяет класс, в котором начинается поиск имени.
void C::ff() { f(); A::f(); B::f(); } |
// Вызов функции f() из класса C // Вызов функции f() из класса A // Снова вызов функции f() из класса A, т.к. в классе В функция f() не определена |