Загружаем изображение…
Глава 13. Наследование классов
Виртуальные функции.
Теперь рассмотрим такой случай, что у наших классов есть метод Show().
Сделаем указатель типа Person (базового класса) на производный класс Student и попытаемся вывести данные объекта. В заголовочном фале person.h в производном классе добавили метод Show(), где:
Person::Show(); выводит данные от базового класса, а в производном, соответственно, добавили вывод grade (класс, в котором учится ученик).
Вывод консоли:
Ivan, 12
Peter, 12, grade 5
Peter, 12
Как можем заметить, grade не был выведен указателем pp. Здесь показано статическое связывание, то есть тип указателя Person, в связи с чем была выведена часть данных метода класса Person, несмотря на то что указатель pp ссылается на объект класса Student.
Чтобы решить эту проблему добавим к методу Show класса Person virtual, то есть сделаем динамическое связывание.
Теперь в консоли получили такие данные:
Ivan, 12
Peter, 12, grade 5
Peter, 12, grade 5
Но нам следует добавить виртуальный деструктор, иначе может произойти утечка virtual ~Person(){}.
Виртуальные функции.
Теперь рассмотрим такой случай, что у наших классов есть метод Show().
//заголовочный файл person.h
#pragma once
#include <string>
class Person {
protected:
std::string m_name;
int m_age;
public:
Person() : m_name("Noname"), m_age(0) {}
Person(std::string name, int age) : m_name(name), m_age(age) {}
void Show() const { std::cout << m_name << ", " << m_age; }
};
class Student : public Person {
private:
int m_grade;
public:
Student() : Person("Noname", 0), m_grade(0) {}
Student(std::string name, int age, int grade)
: Person(name, age), m_grade(grade) {}
void Show() const {
Person::Show();
std::cout << ", grade " << m_grade << std::endl;
}
};
Сделаем указатель типа Person (базового класса) на производный класс Student и попытаемся вывести данные объекта. В заголовочном фале person.h в производном классе добавили метод Show(), где:
Person::Show(); выводит данные от базового класса, а в производном, соответственно, добавили вывод grade (класс, в котором учится ученик).
//main.cpp
#include <iostream>
#include "person.h"
int main() {
Person Ivan("Ivan", 12);
Ivan.Show();
std::cout << std::endl;
Student Peter("Peter", 12, 5);
Peter.Show();
Person* pp = &Peter;
pp->Show();
return 0;
}
Вывод консоли:
Ivan, 12
Peter, 12, grade 5
Peter, 12
Как можем заметить, grade не был выведен указателем pp. Здесь показано статическое связывание, то есть тип указателя Person, в связи с чем была выведена часть данных метода класса Person, несмотря на то что указатель pp ссылается на объект класса Student.
Чтобы решить эту проблему добавим к методу Show класса Person virtual, то есть сделаем динамическое связывание.
virtual void Show() const { std::cout << m_name << ", " << m_age; }
Теперь в консоли получили такие данные:
Ivan, 12
Peter, 12, grade 5
Peter, 12, grade 5
Но нам следует добавить виртуальный деструктор, иначе может произойти утечка virtual ~Person(){}.