Спадкування класів в C ++

  1. Створення базового класу
  2. Спадкування від базового класу
  3. Конструктор базового класу
  4. Створення об'єкта класу student
  5. Створення класу-спадкоємця teacher
  6. Створення об'єкта класу teacher
  7. Коли потрібно використовувати конструктор

Спадкування дозволяє уникнути дублювання зайвого коду при написанні класів . Нехай в базі даних ВНЗ а повинна зберігатися інформація про всіх студентів та викладачів. Представляти всі дані в одному класі не вийде, оскільки для викладачів нам знадобиться зберігати дані, які для студента не застосовні, і навпаки.

Створення базового класу

Для вирішення цього завдання створимо базовий клас human, який буде описувати модель людини. У ньому будуть зберігатися ім'я, прізвище та по батькові.

Створіть файл human.h:

// human.h #ifndef HUMAN_H_INCLUDED #define HUMAN_H_INCLUDED #include <string> #include <sstream> class human {public: // Конструктор класу human human (std :: string last_name, std :: string name, std :: string second_name ) {this-> last_name = last_name; this-> name = name; this-> second_name = second_name; } // Отримання ПІБ людини std :: string get_full_name () {std :: ostringstream full_name; full_name << this-> last_name << "" << this-> name << "" << this-> second_name; return full_name.str (); } Private: std :: string name; // ім'я std :: string last_name; // прізвище std :: string second_name; // батькові}; #endif // HUMAN_H_INCLUDED

Спадкування від базового класу

Тепер створіть новий клас student, який буде спадкоємцем класу human. Помістіть його в файл student.h.

// student.h #ifndef STUDENT_H_INCLUDED #define STUDENT_H_INCLUDED #include "human.h" #include <string> #include <vector> class student: public human {public: // Конструктор класу Student student (std :: string last_name, std :: string name, std :: string second_name, std :: vector <int> scores): human (last_name, name, second_name) {this-> scores = scores; } // Отримання середнього бала студента float get_average_score () {// Загальна кількість оцінок unsigned int count_scores = this-> scores.size (); // Сума всіх оцінок студента unsigned int sum_scores = 0; // Середній бал float average_score; for (unsigned int i = 0; i <count_scores; ++ i) {sum_scores + = this-> scores [i]; } Average_score = (float) sum_scores / (float) count_scores; return average_score; } Private: // Оцінки студента std :: vector <int> scores; }; #endif // STUDENT_H_INCLUDED

Функція get_average_score обчислює середнє арифметичне всіх оцінок студента. Усе публічні властивості і методи класу human будуть доступні в класі student.

Конструктор базового класу

Для того, щоб ініціалізувати конструктор батьківського класу (в нашому випадку - це збереження імені, прізвища та по батькові учня), використовується наступний синтаксис:

// Конструктор класу Student student (// аргументи конструктора поточного класу): human (// ініціалізація конструктора батьківського класу) {// ініціалізація конструктора поточного класу}

У конструктор класу human ми передаємо ініціали людини, які зберігаються в екземплярі класу. Для класу students, нам необхідно задати ще і список оцінок студента. Тому конструктор students приймає всі аргументи конструктора базового класу, а також додаткові аргументи для розширення функціоналу:

// Конструктор класу Student student (std :: string last_name, std :: string name, std :: string second_name, std :: vector <int> scores): human (last_name, name, second_name) {this-> scores = scores ; }

Список оцінок студента зберігається в векторі .

Створення об'єкта класу student

Реалізуємо призначений для користувача інтерфейс для роботи з класом student.

// main.cpp #include <iostream> #include <vector> #include "human.h" #include "student.h" int main (int argc, char * argv []) {// Оцінки студента std :: vector <int> scores; // Додавання оцінок студента в вектор scores.push_back (5); scores.push_back (3); scores.push_back (2); scores.push_back (2); scores.push_back (5); scores.push_back (3); scores.push_back (3); scores.push_back (3); scores.push_back (3); // Створення об'єкта класу student student * stud = new student ( "Петров", "Іван", "Олексійович", scores); // Висновок повного імені студента (використовується успадкований метод класу human) std :: cout << stud-> get_full_name () << std :: endl; // Висновок середнього бала студента std :: cout << "Середній бал:" << stud-> get_average_score () << std :: endl; return 0; }

У цьому прикладі ми написали програму, яка створює об'єкт класу student, зберігаючи в ньому його ім'я, прізвище, по батькові та список оцінок.

Після ініціалізації об'єкта, відбувається висновок повного імені студента за допомогою функції get_full_name. Ця функція була успадкована від базового класу human.

Потім програма вичісліяет середній бал студента і виводить його на екран. Цим займається функція get_average_score, яку ми описали всередині класу student. Потім програма вичісліяет середній бал студента і виводить його на екран

Ми реалізували частину функціоналу для нашої бази даних інституту (я звичайно перебільшую, коли оперую настільки серйозними висловлюваннями про справжню базу даних :)

Створення класу-спадкоємця teacher

Потрібно створити ще один клас, в якому будуть зберігатися дані викладачів. Дамо йому назву - teacher. Як ви вже зрозуміли, ми не будемо описувати всі методи цього класу з нуля, а просто успадкуємо його від класу human. Тоді, не потрібно буде реалізовувати зберігання імені, прізвища та по батькові препода. Це вже є в базовому класі human.

Створіть файл teacher.h:

// teacher.h #ifndef TEACHER_H_INCLUDED #define TEACHER_H_INCLUDED #include "human.h" #include <string> class teacher: public human {// Конструктор класу teacher public: teacher (std :: string last_name, std :: string name, std :: string second_name, // Кількість навчальних годин за семетр у викладача unsigned int work_time): human (last_name, name, second_name) {this-> work_time = work_time; } // Отримання кількості навчальних годин unsigned int get_work_time () {return this-> work_time; } Private: // Навчальні години unsigned int work_time; }; #endif // TEACHER_H_INCLUDED

У класу teacher з'явилося нове властивість - кількість навчальних годин, відведений викладачу на одиницю часу (семестр). Весь інший функціонал успадковується від базового класу human. Якби ми писали все з нуля, то однакового коду б вийшло в рази більше, і його підтримка ускладнилася б на порядок.

Створення об'єкта класу teacher

Змінимо вміст файлу main.cpp, щоб перевірити роботу класу teacher.

#include <iostream> #include "human.h" #include "teacher.h" int main (int argc, char * argv []) {// Кількість навчальних годин викладача unsigned int teacher_work_time = 40; teacher * tch = new teacher ( "Васильків", "Петро", "Сергійович", teacher_work_time); std :: cout << tch-> get_full_name () << std :: endl; std :: cout << "Кількість годин:" << tch-> get_work_time () << std :: endl; return 0; }

Якщо збірка програми пройшла без помилок, то результат роботи програми буде таким:

Можна таким же чином створити клас, в якому будуть зберігатися дані обслуговуючого персоналу або керівного складу. Спадкування використовують, коли у кожної групи об'єктів є загальні параметри, але для кожної з цих груп потрібно зберігати більш кастомниє дані.

Також, ми можемо створити клас, який буде описуючи студента заочної форми навчання. Його ми успадкували б від класу student, додавши будь-які додаткові дані.

В клас human можна додати ще більше властивостей, які будуть описувати дані, наявні у будь-якої людини. Наприклад, номер паспорта, дату народження, прописку та місце проживання.

Подібний підхід дозволяє в рази зменшити дублювання коду в реальних проектах, і вблагати його підтримку.

Коли потрібно використовувати конструктор

Якщо у класу багато властивостей - їх зовсім не обов'язково ставити в конструкторі. Для збереження окремих властивостей класу використовують set-функції. Наприклад, для збереження номера паспорта, можна створити публічний метод set_passport_number (std :: string number), який буде приймати значення властивості і зберігати його в об'єкті, через змінну this.

Наступний урок - перевантаження функцій в C ++.