Наследование позволяет производным классам получать поля и методы родительских классов, дополнять и изменять их.
Наследование позволяет многократно использовать существующий код.
Наследование используется, когда базовый класс включает производный класс как подмножество (отношение «является»).
Простое наследование предполагает один родительский класс, множественное – несколько.
class имя : [ доступ ] баз. класс
{ описание класса
};
Доступ:
- private
- protected
- public
#include
#include
class animal
{ char name[20];
public:
animal (char * n = "") { strcpy(name,n); }
void say() { cout
void hungry() { say(); say(); say(); }
};
class dog : public animal
{ public:
dog (char * n = ""): animal(n) {};
void say() { animal::say (); cout
};
class cat : private animal
{ public:
cat (char * n = ""): animal(n) {};
void say() { animal::say (); cout
};
int main()
{ dog f("filya");
cat c("murka");
f.say(); f.hungry();
с.say(); // с.hungry();
return 0;
}
Конструкторы не наследуются. Если конструктор базового класса явно не вызван, то вызывается конструктор по умолчанию (без параметров).
Не наследуется операция присваивания.
Деструкторы не наследуются. Деструктор по умолчанию вызывает деструктор базового класса.
Указателю на объект базового класса можно присвоить адрес объекта любого производного класса.
animal * a = new dog;
При использовании обычных методов будут вызваны методы базового класса.
Для того, чтобы в зависимости от конкретного типа объекта вызывались нужные методы, необходимо позднее связывание. Этот механизм реализуется виртуальными методами.
В описании виртуального метода используется спецификатор virtual.
Для класса, использующего виртуальные методы, компилятор создаст таблицу виртуальных методов, содержащую адреса методов. При вызове метода адрес выбирается из этой таблицы.
say(); f-hungry(); c-say(); return 0; } " width="640"
int main()
{ animal * f = new dog ("filya");
animal * c = new cat ("murka");
f-say(); f-hungry();
c-say();
return 0;
}
class animal
{ char name[20];
public:
animal (char * n = "") { strcpy(name,n); }
virtual void say() { cout
void hungry() { say(); say(); say();}
};
Метод, переопределяющий виртуальный метод, должен иметь то же имя и набор параметров.
Виртуальные методы наследуются.
Виртуальные методы не могут быть статическими.
Деструкторы должны быть виртуальными, чтобы правильно освобождать память объектов.
Методы, не определенные в базовом классе, должны быть описаны как чисто виртуальные.
Чисто виртуальные методы и абстрактные классы
Чисто виртуальный метод вместо тела содержит признак = 0. Такой метод обязательно должен быть переопределен в производном классе.
Абстрактным называется класс, содержащий чисто виртуальные методы.
Абстрактный класс является базовым для других классов. Его объекты создавать нельзя, поскольку обращение к чисто виртуальному методу вызывает ошибку. Допускается описывать указатели и ссылки на объекты абстрактных классов.
class animal
{ char name[20];
public:
animal (char * n = "") { strcpy(name,n); }
virtual void say() = 0;
void hungry() { say(); say(); say(); }
};
class dog : public animal
{ public:
dog (char * n = ""): animal(n) {};
void say() { cout
};
class A
{ …
};
class B
{ …
};
class C: public A, public B
{ …
};
#include
#include
class A {
public:
void show() { cout
};
class B {
public:
void show() { cout
};
class C: public A, public B {
};
int main ()
{ C object; object.A::show();
object.B::show(); }
Неопределенность при множественном наследовании
Структуры – частный случай классов. Отличаются по умолчанию public доступом.
В объединениях
- Нельзя использовать спецификаторы доступа
- Нельзя указать родительский класс
- Нельзя использовать статические элементы

Наследование. С++ (50 KB)

