Скачать презентацию Наследование Занятие 3 Ключи доступа class имя Скачать презентацию Наследование Занятие 3 Ключи доступа class имя

Наследование.pptx

  • Количество слайдов: 13

Наследование Занятие 3 Наследование Занятие 3

Ключи доступа class имя : [private | protected | public] базовый класс { тело Ключи доступа class имя : [private | protected | public] базовый класс { тело класса }; class A { …}; class B { …}; class C { …}; class D: A, protected B, public C { …}; По умолчанию для всех классов используется ключ доступа private.

Соответствие ключей доступа Ключ доступа Спецификатор в базовом Доступ в производном классе private protected Соответствие ключей доступа Ключ доступа Спецификатор в базовом Доступ в производном классе private protected public нет private protected public нет protected public private protected public нет protected public class Base{ … public: void f(); }; class Derived : private Base { … public : Base: : void f(); };

Простое наследование Производный класс имеет одного родителя. Конструкторы не наследуются. Производный класс должен иметь Простое наследование Производный класс имеет одного родителя. Конструкторы не наследуются. Производный класс должен иметь собственные конструкторы. Порядок вызова конструкторов: • Если в конструкторе производного класса явный вызов базового класса отсутствует, автоматически вызывается конструктор базового класса по умолчанию (без параметров). • Для иерархии, состоящей из нескольких уровней, конструкторы базовых классов вызываются начиная с самого верхнего уровня. После этого выполняется конструкторы тех элементов класса, которые являются объектами, в порядке их объявления в классе, а затем исполняется конструктор класса. • В случае нескольких базовых классов их конструкторы вызываются в порядке объявления. Операция присваивания не наследуется.

Правила наследования деструкторов • Деструкторы не наследуются, и если программист не описал в производном Правила наследования деструкторов • Деструкторы не наследуются, и если программист не описал в производном классе деструктор, он формируется по умолчанию и вызывает деструкторы всех базовых классов. • В отличие от конструкторов, при написании деструктора производного класса в нем не требуется явно вызывать деструкторы базовых классов, поскольку это будет сделано автоматически. • Для иерархии классов, состоящей из нескольких уровней, деструкторы вызываются в порядке, строго обратном вызову конструкторов: сначала вызывается деструктор класса, затем – деструкторы элементов класса, а потом деструктор базового класса.

Пример enum color {red, green, blue}; class monstr { int health, ammo; color skin; Пример enum color {red, green, blue}; class monstr { int health, ammo; color skin; char *name; public: // -----конструкторы monstr (int he = 100, int am = 10); monstr (color sk); monstr (char *nam); monstr (const monstr &M) ; // ----деструктор ~monstr() { delete [] name; } // ----Методы доступа к полям int get_health() const { return health; } int get_ammo() const { return ammo; } // ----Методы, изменяющие значения полей void change_health(int he) { health = he; } //----- Прочие методы void draw(int x, int y, int scale, int position);

Пример, продолжение } // ----операции monstr & operator ++ (){++health; return *this; } monstr Пример, продолжение } // ----операции monstr & operator ++ (){++health; return *this; } monstr & operator ++ (int){ monstr M(*this); health++; return M; bool operator > (const monstr &M){ if (health > M. health) return true; return false; } operator int() { return health; } const monstr & operator = (const monstr &M) { if (&M == this) return *this; if (name) delete [] name; if ( M. name) { name = new char [strlen(M. name) + 1); strcpy(name, M. name); } else name = 0; health = M. health; ammo = M. ammo; skin = M. skin; return *this; } }

Пример, продолжение //---Реализация класса monstr: : monstr (int he, int am) { health = Пример, продолжение //---Реализация класса monstr: : monstr (int he, int am) { health = he; ammo = am; } monstr: : monstr (const monstr &M) { if (M. name) { name = new char [strlen(M. name) + 1]; strcpy (name, M. name); } else name = 0; health = M. health; ammo = M. ammo; skin = M. skin; } monstr: : monstr(color sk) { switch (sk) { case red : health = 100; ammo =10; skin = red; name = 0; break; case green: health = 100; ammo =20; skin=green; name = 0; break; case blue: health = 100; ammo =40; skin = blue; name = 0; break; } } monstr: : monstr(char *nam) { name = new char [strlen(nam) + 1]; strcpy (name, nam); health = 100; ammo = 10; skin = red; } void monstr: : draw(int x, int y, int scale, int position) { /* отрисовка monstr*/ }

Пример, продолжение: производный класс class daemon : public monstr { int brain; public: // Пример, продолжение: производный класс class daemon : public monstr { int brain; public: // -----конструкторы daemon (int br = 10){brain =10}; daemon (color sk) : monstr (sk){ brain =10 }; daemon (char *nam) : monstr(nam) { brain =10 }; daemon (const daemon &M) : monstr(M) {brain =M. brain}; // ----операции const daemon & operator = (const daemon &M) { if (&M == this) return *this; brain =M. brain; monstr : : operator = (M); return *this; } // ----Методы, изменяющие значения полей void think(); //----- Прочие методы void draw(int x, int y, int scale, int position); }

Пример, продолжение: реализация производного класса void daemon : : think() { /*… */}; void Пример, продолжение: реализация производного класса void daemon : : think() { /*… */}; void daemon : : draw(int x, int y, int scale, int position) { /* Отрисовка daemon */; }

Раннее связывание Работа с объектами чаще всего производится через указатели. Указателю на базовый класс Раннее связывание Работа с объектами чаще всего производится через указатели. Указателю на базовый класс можно присвоить значение адреса объекта производного класса. monstr *p; p = new daemon; p->draw(1, 1, 1, 1); //будет вызван метод класса monstr ((daemon *)p)->draw(1, 1, 1, 1);

Виртуальные методы virtual void draw(int x, int y, int scale, int position) ; Виртуальным Виртуальные методы virtual void draw(int x, int y, int scale, int position) ; Виртуальным называется метод, ссылка на который разрешается на этапе выполнения программы. Правила описания и использования виртуальных методов. • Если в базовом классе метод определен как виртуальный, метод, определенный в производном классе с тем же именем и набором параметров, автоматически становится виртуальным, а с отличающимся набором параметров – обычным. • Виртуальные методы наследуются, т. е. переопределять из в производном классе требуется только при необходимости задать отличающиеся действия. • Если виртуальный метод переопределяется в производном классе, объекты этого класса могут получить доступ к методу базового класса с помощью операции доступа к области видимости. • Виртуальный метод не может объявляться с модификатором static, но может быть объявлен как дружественный. • Если в классе вводится описание виртуального метода, он должен быть определен хотя бы как чисто виртуальный.

Абстрактный класс Чисто виртуальный метод содержит признак = 0 вместо тела. virtual void f Абстрактный класс Чисто виртуальный метод содержит признак = 0 вместо тела. virtual void f (int) = 0; Чисто виртуальный метод должен переопределяться в производном классе (возможно, опять как чисто виртуальный). Класс, содержащий хотя бы один чисто виртуальный метод, называется абстрактным. Виртуальный механизм работает только при использовании указателей или ссылок на объекты. Объект, определенный через указатель или ссылку и содержащий виртуальные методы, называется полиморфным.