27. C++ Наследование

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

Как говорилось во введении в c++ в классах можно выполнять наследование, т.е. передавать все или часть свойств класса родителя классу наследнику и дополнять их.

Общий вид наследования выглядит так:

class имя_нового_класса: модификатор_доступа наследуемый_класс
{
     //тело нового класса
}

Модификаторы доступа при наследовании мы уже рассматривали в теме «модификаторы доступа»

Продемонстрируем на примере:

//Создадим класс Person
class Person
{
public:
  Person()
  {
      this->Name="Vasya";
      this->age= new unsigned int (20); //создание переменной в динамической памяти
  }

  ~Person()
  {
      delete age; //удаление переменной в динамической памяти
  }

 void getInfo()
 {
   cout<<"Name: "<< this->Name <<" age "<< *(this->age) <<endl; //выводим данные на экран
 }


protected:
  string Name;
  unsigned int * age; //указатель на переменную в динамической памяти
};

И унаследуем от него класс student (студент – это человек, который учится на каком-то курсе, поэтому добавим ему поле курс и метод getInfoStudent())

class student : public Person
{
   public:
    student(uint course)
    {
        this->course=course;
    }

    void getInfoStudent()const
    {
      cout<<"Name: "<< this->Name <<" age "<< *(this->age) <<" studing at "<course<<" course"<<endl; //выводим данные на экран
    }
    uint course;
};

Теперь в функции main мы можем вызвать:

    cout<<"c_Person created"<<endl;
    Person c_Person;
    c_Person.getInfo();

    cout<<endl<<endl;

    cout<<"c_Student created"<<endl;
    student c_Student(2);
    c_Student.getInfo();
    c_Student.getInfoStudent();

Здесь мы создали объект класса Person  и у него доступен только 1 метод getInfo(), после мы создали объект класса student и у него доступны как метод базового класса getInfo(), так и метод getInfoStudent(), в этом методе выводится номер курса
Отдельно стоит отметить модификатор доступа protected: в базовом классе – за счет него и модификатора при наследовании public мы имеем доступ к полям Name и age базового класса (что к слову может нести некоторый риск, например при работе с указателем age, для защиты, используем ключевое слово const).

Немного оговоримся про организацию памяти и вызовы конструкторов и деструкторов:
Для создания класса наследника (
student) мы должны сначала создать класс родитель т.к. нам нужны его поля и лишь потом вызвать класс наследник
При уничтожении (вызове деструктора) сначала вызывается деструктор класса наследника, потом класса родителя.

Так как в этом примере данные в классе-наследнике хранятся на стеке – отдельно создавать деструктор нет необходимости (подойдет и по умолчанию).
Переменная по указателю age удалится в деструкторе базового класса.

К слову о наследовании –нам ничто не мешает от класса student или Person унаследовать еще класс/классы.

И главный момент – зачем это нужно?

  1. отсутствие дублирования кода-нам не нужно заново переписывать функции во всех классах-наследниках
  2. более четкое выделение структуры и методов работы с классами (логика наследования)
  3. у наследования есть еще одна особенность – указатель на базовый класс является указателем и на классы наследники:
    Что это значит – мы можем создать функцию, принимающую в качестве аргумента базовый класс, а «подсунуть» ему класс наследник.
    Особенно ярко это будет видно в следующей теме про виртуальные методы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *