Класс наследование c++

Наследование является одной из главных особенностей объектно-ориентированного программи­рования. В С++ наследование поддерживается за счет того, что одному классу разрешается при своем объявлении включать в себя другой класс. Наследование позволяет построить иерархию классов от более общего к более частным. Этот процесс включает в себя определение базового класса, определяющего общие качества всех объектов, которые будут выведены затем из базового класса. Базовый класс представляет собой наиболее общее описание. Выведенные из базового класса классы обычно называют производными классами. Производные классы включают в себя все черты базового класса и, кроме того, добавляют новые качества, характерные именно для данного про­изводного класса. Чтобы продемонстрировать, как работает этот процесс, в следующем примере созданы классы, классифицирующие различные типы средств передвижения.
В качестве начального рассмотрим класс, названный road_vehicle (дорожное средство передви­жения), который служит очень широким определением средств передвижения по дорогам. Он хранит информацию о числе колес движущегося средства и о числе пассажиров, которые он может вмещать:

class road_vehicle <
int wheels;
int passengers;
public:
void set_wheels(int num);
int get_wheels();
void set_pass(int num);
int get_pass();
>;

Теперь можно использовать это определение дорожного средства передвижения для того, что­бы определить конкретные типы. Например, в следующем фрагменте кода определен класс truck (грузовик), используя класс road_vehicle:

class truck: public road_vehicle <
int cargo;
public:
void set_cargo(int size);
int get_cargo();
void show();
>;

Обратим внимание, каким образом наследуется класс road_vehicle. Общая форма записи насле­дования имеет следующий вид

class имя_нового_класса: доступ наследуемый_класс <
//тело нового класса
>

Здесь использование доступ факультативно, но если оно используется, то должно принимать значение public или private. Пока же все наследуемые классы будут использовать спецификатор public. Он означает, что все члены класса-предшественника, имеющие спецификатор доступа public, сохраняют тот же спецификатор досту­па во всех производных классах. Поэтому в данном примере члены класса truck имеют доступ к функциям-членам класса road_vehicle так, как если бы эти функции-члены были объявлены внут­ри класса truck. Однако функции-члены класса truck не имеют доступа к частным членам класса road_vehicle.

Следующая программа иллюстрирует наследование с помощью создания двух подклассов клас­са road_vehicle: truck и automobile:

#include
class road_vehicle <
int wheels;
int passengers;
public:
void set_wheels(int num);
int get_wheels ();
void set_pass(int num);
int get_pass ();
>;
class truck: public road_vehicle <
int cargo;
public:
void set_cargo(int size);
int get_cargo();
void show ();
>;
enum type ;
class automobile: public road_vehicle <
enum type car_type;
public:
void set_type (enum type t);
enum type get_type();
void show();
>;
void road_vehicle::set_wheels(int num)
<
wheels = num;
>
int road_vehicle::get_wheels()
<
return wheels;
>
void road_vehicle::set_pass(int num)
<
passengers = num;
>
int road_vehicle::get_pass()
<
return passengers;
>
void truck::set_cargo(int num)
<
cargo = num;
>
int truck::get_cargo ()
<
return cargo;
>
void truck::show ()
<
cout

Наследование класса базового перечисления

Есть ли шаблон, в котором я могу наследовать перечисление из другого перечисления в С++?

Что-то вроде этого:

Невозможно. Наследования с перечислениями нет.

Вместо этого вы можете использовать классы с named const ints.

Вы не можете сделать это напрямую, но вы можете попытаться использовать решение из этой статьи.

Основная идея заключается в использовании класса-помощника-шаблона, который содержит значения перечислений и имеет оператор типа cast. Учитывая, что базовый тип для перечисления int , вы можете легко использовать этот класс владельца в своем коде вместо enum.

К сожалению, это невозможно в С++ 14. Надеюсь, у нас будет такая языковая функция в С++ 17. Поскольку у вас уже есть несколько обходных решений для вашей проблемы, я не буду предлагать решение.

Я хотел бы указать, что формулировка должна быть «расширением», а не «наследованием». Расширение допускает больше значений (поскольку вы переходите от 3 до 6 значений в вашем примере), тогда как наследование означает добавление большего количества ограничений к заданному базовому классу, поэтому набор возможностей сжимается. Следовательно, потенциальное кастинг будет работать в точности противоположно наследованию. Вы можете отличить производный класс к базовому классу, а не наоборот, с наследованием класса. Но когда вы имеете расширения, вы «должны» уметь применять базовый класс к его расширению, а не наоборот. Я говорю «должен», потому что, как я уже сказал, такой языковой функции по-прежнему не существует.

Как насчет этого? Ок, экземпляр создается для каждого возможного значения, но, кроме того, он очень гибкий. Есть ли недостатки?

Доступно про наследование в С++

Предполагается, что вы уже знакомы с понятиями класс, объект, функция, переменная и т.д. В статье пойдет речь о понятии наследования со всеми вытекающими. Если приведенный в конце код вам понятен, не тратьте на нее время.

Допустим, создается стратегическая игра и поставлена задача создания всяческих боевых и не боевых единиц. Начнем с создания фермера, но так как фермеров будет много и все разные, но с одинаковыми параметрами, характеризующими определенного фермера, логично будет создать его класс, а самих фермеров задавать как объекты этого класса:

  Образец заполнения заявление на получение паспорта

С этим классом должно быть все понятно. Его объекты будут характеризоваться одним параметром » health » (здоровье) и есть один метод, позволяющий вывести значение этого параметра на экран. Можно создавать фермеров:

На экран выведется Unit health: 10 и Unit health: 30. Ничего нового пока.

Теперь создадим воинов. Кроме того, что у них есть здоровье, как у фермеров, они могут наносить урон ( damage ). Можно было бы создать отдельный класс для воинов с параметрами health и damage , но гораздо проще создать класс воинов, имеющий параметр health класса фермеров и свой параметр damage . Это и есть наследование:

То есть теперь, создавая объект класса Soldier , можно использовать как его поля, так и поля базового класса Unit :

В результате у Геракла теперь 10 healthи 30 damage, а у Ахиллеса 40 healthи 50 damage. Сейчас я поясню несколько моментов, которые могли вызвать затруднения, но сначала необходимо изменить метод доступа поля health класса Unitс privateна protected, чтобы код скомпилировался. protectedотличается отprivateтем, что protectedне запрещает доступ к полям классам-наследникам.

Теперь о моментах:
-при объявлении класса-наследника необходимо представить базовый класс:
class Soldier : public Unit
-при объявлении базового класса необходимо предоставить модификатор доступа (public, private, protected) перед именем базового класса. Модификаторpublic позволяет классу-наследнику наследовать поля базового класса так, как они объявлены в базовом классе, protectedпреобразует public в protected, а модификатор privateнаследует поля базового класса, как private, вне зависимости от того, как они заданы в базовом классе. Следует отметить, что наследование ни как не изменяет базовый класс
-в представленном наследнике, для примера, введено несколько конструкторов. При создании объекта класса Soldier, в случае первых двух конструкторов для инициализации полей базового класса Unitбудет использоваться его конструктор по умолчанию. Третий же конструктор Soldier вызывает конструктор с параметром базового Unit

Хорошо, теперь аналогичным образом создадим лошадей, которые в отличии от фермеров, будут двигаться, т.е. будут иметь параметр speed:

Все лошади будут иметь 10 healthи 20 speed.

А теперь создадим всадников, которые будут иметь характеристики как фермеров(здоровье) и солдат (damage), так и лошадей (speed):

И все бы ничего, но наследуя и Horseи Soldier, Horsemanнаследует 2 копии Unit. Решить эту проблему можно использовав ключевое слово virtualперед объявлениями о наследовании класса Unit(не путайте с виртуальными функциями):

Все, класс всадников создан! При создании объекта класса Horsemanбудут использоваться конструкторы по умолчанию базовых классов.

Допустим, что солдат тоже может двигаться (имеет параметр speed):

Неоднозначность можно решить дважды использовав оператор разрешения контекста:

Но правильнее было бы переназначить поле в классе Horseman (код целиком):

Если Вам понравилась статья, проголосуйте за нее

Голосов: 0 Голосовать

Наследование — это механизм создания нового класса на основе уже существующего. При этом к существующему классу могут быть добавлены новые элементы (данные и функции), либо существующие функции могут быть изменены. Основное назначение механизма наследования — повторное использование кодов, так как большинство используемых типов данных являются вариантами друг друга, и писать для каждого свой класс нецелесообразно.
Объекты разных классов и сами классы могут находиться в отношении наследования, при котором формируется иерархия объектов, соответствующая заранее предусмотренной иерархии классов.

Иерархия классов позволяет определять новые классы на основе уже имеющихся. Имеющиеся классы обычно называют базовыми (иногда порождающими), а новые классы, формируемые на основе базовых, – производными (порожденными, классами-потомками или наследниками).

Производные классы «получают наследство» – данные и методы своих базовых классов, и могут пополняться собственными компонентами (данными и собственными методами). Наследуемые компоненты не перемещаются в производный класс, а остаются в базовых классах. Сообщение, обработку которого не могут выполнить методы производного класса, автоматически передается в базовый класс. Если для обработки сообщения нужны данные, отсутствующие в производном классе, то их пытаются отыскать автоматически в базовом классе.

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

Для порождения нового класса на основе существующего используется следующая общая форма

При объявлении порождаемого класса МодификаторДоступа может принимать значения public , private , protected либо отсутствовать, по умолчанию используется значение private . В любом случае порожденный класс наследует все члены базового класса, но доступ имеет не ко всем. Ему доступны общие ( public ) члены базового класса и недоступны частные ( private ).

Для того, чтобы порожденный класс имел доступ к некоторым скрытым членам базового класса, в базовом классе их необходимо объявить со спецификацией доступа защищенные ( protected ).

Члены класса с доступом protected видимы в пределах класса и в любом классе, порожденном из этого класса.

Общее наследование

При общем наследовании порожденный класс имеет доступ к наследуемым членам базового класса с видимостью public и protected . Члены базового класса с видимостью private – недоступны.

Наследование классов в C++ — урок 13

Создание базового класса

Для решения этой задачи создадим базовый класс human , который будет описывать модель человека. В нем будут храниться имя, фамилия и отчество.

  Как начисляется пенсия в беларуси

Создайте файл human.h :

Наследование от базового класса

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

Функция get_average_score вычисляет среднее арифметическое всех оценок студента. Все публичные свойства и методы класса human будут доступны в классе student .

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

Для того, чтобы инициализировать конструктор родительского класса (в нашем случае — это сохранение имени, фамилии и отчества ученика), используется следующий синтаксис:

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

Список оценок студента хранится в векторе.

Создание объекта класса student

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

В этом примере мы написали программу, которая создает объект класса student , сохраняя в нем его имя, фамилию, отчество и список оценок.

После инициализации объекта, происходит вывод полного имени студента с помощью функции get_full_name . Эта функция была унаследована от базового класса human .

Затем программа вычислияет средний балл студента и выводит его на экран. Этим занимается функция get_average_score , которую мы описали внутри класса student .

Мы реализовали часть функционала для нашей базы данных института (я конечно утрирую, когда оперирую столь серьезными высказываниями про настоящую базу данных 🙂

Создание класса-наследника teacher

Нужно создать еще один класс, в котором будут храниться данные преподавателей. Дадим ему название — teacher . Как вы уже поняли, мы не будем описывать все методы этого класса с нуля, а просто унаследуем его от класса human . Тогда, не нужно будет реализовывать хранение имени, фамилии и отчества препода. Это уже есть в базовом классе human .

Создайте файл teacher.h :

У класса teacher появилось новое свойство — количество учебных часов, отведенное преподавателю на единицу времени (семестр). Весь остальной функционал наследуется от базового класса human . Если бы мы писали все с нуля, то одинакового кода бы получилось в разы больше, и его поддержка усложнилась бы на порядок.

Создание объекта класса teacher

Изменим содержимое файла main.cpp , чтобы проверить работу класса teacher .

Если сборка программы прошла без ошибок, то результат работы программы будет таким:

Можно таким же образом создать класс, в котором будут храниться данные обслуживающего персонала или руководящего состава. Наследование используют, когда у каждой группы объектов есть общие параметры, но для каждой из этих групп нужно хранить более кастомные данные.

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

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

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

Когда нужно использовать конструктор

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

Наследование классов в C++ — урок 13

Создание базового класса

Для решения этой задачи создадим базовый класс human , который будет описывать модель человека. В нем будут храниться имя, фамилия и отчество.

Создайте файл human.h :

Наследование от базового класса

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

Функция get_average_score вычисляет среднее арифметическое всех оценок студента. Все публичные свойства и методы класса human будут доступны в классе student .

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

Для того, чтобы инициализировать конструктор родительского класса (в нашем случае — это сохранение имени, фамилии и отчества ученика), используется следующий синтаксис:

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

Список оценок студента хранится в векторе.

Создание объекта класса student

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

В этом примере мы написали программу, которая создает объект класса student , сохраняя в нем его имя, фамилию, отчество и список оценок.

После инициализации объекта, происходит вывод полного имени студента с помощью функции get_full_name . Эта функция была унаследована от базового класса human .

Затем программа вычислияет средний балл студента и выводит его на экран. Этим занимается функция get_average_score , которую мы описали внутри класса student .

Мы реализовали часть функционала для нашей базы данных института (я конечно утрирую, когда оперирую столь серьезными высказываниями про настоящую базу данных 🙂

Создание класса-наследника teacher

Нужно создать еще один класс, в котором будут храниться данные преподавателей. Дадим ему название — teacher . Как вы уже поняли, мы не будем описывать все методы этого класса с нуля, а просто унаследуем его от класса human . Тогда, не нужно будет реализовывать хранение имени, фамилии и отчества препода. Это уже есть в базовом классе human .

  Как лучше оформить колодец

Создайте файл teacher.h :

У класса teacher появилось новое свойство — количество учебных часов, отведенное преподавателю на единицу времени (семестр). Весь остальной функционал наследуется от базового класса human . Если бы мы писали все с нуля, то одинакового кода бы получилось в разы больше, и его поддержка усложнилась бы на порядок.

Создание объекта класса teacher

Изменим содержимое файла main.cpp , чтобы проверить работу класса teacher .

Если сборка программы прошла без ошибок, то результат работы программы будет таким:

Можно таким же образом создать класс, в котором будут храниться данные обслуживающего персонала или руководящего состава. Наследование используют, когда у каждой группы объектов есть общие параметры, но для каждой из этих групп нужно хранить более кастомные данные.

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

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

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

Когда нужно использовать конструктор

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

Наследование классов в C++ — урок 13

Создание базового класса

Для решения этой задачи создадим базовый класс human , который будет описывать модель человека. В нем будут храниться имя, фамилия и отчество.

Создайте файл human.h :

Наследование от базового класса

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

Функция get_average_score вычисляет среднее арифметическое всех оценок студента. Все публичные свойства и методы класса human будут доступны в классе student .

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

Для того, чтобы инициализировать конструктор родительского класса (в нашем случае — это сохранение имени, фамилии и отчества ученика), используется следующий синтаксис:

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

Список оценок студента хранится в векторе.

Создание объекта класса student

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

В этом примере мы написали программу, которая создает объект класса student , сохраняя в нем его имя, фамилию, отчество и список оценок.

После инициализации объекта, происходит вывод полного имени студента с помощью функции get_full_name . Эта функция была унаследована от базового класса human .

Затем программа вычислияет средний балл студента и выводит его на экран. Этим занимается функция get_average_score , которую мы описали внутри класса student .

Мы реализовали часть функционала для нашей базы данных института (я конечно утрирую, когда оперирую столь серьезными высказываниями про настоящую базу данных 🙂

Создание класса-наследника teacher

Нужно создать еще один класс, в котором будут храниться данные преподавателей. Дадим ему название — teacher . Как вы уже поняли, мы не будем описывать все методы этого класса с нуля, а просто унаследуем его от класса human . Тогда, не нужно будет реализовывать хранение имени, фамилии и отчества препода. Это уже есть в базовом классе human .

Создайте файл teacher.h :

У класса teacher появилось новое свойство — количество учебных часов, отведенное преподавателю на единицу времени (семестр). Весь остальной функционал наследуется от базового класса human . Если бы мы писали все с нуля, то одинакового кода бы получилось в разы больше, и его поддержка усложнилась бы на порядок.

Создание объекта класса teacher

Изменим содержимое файла main.cpp , чтобы проверить работу класса teacher .

Если сборка программы прошла без ошибок, то результат работы программы будет таким:

Можно таким же образом создать класс, в котором будут храниться данные обслуживающего персонала или руководящего состава. Наследование используют, когда у каждой группы объектов есть общие параметры, но для каждой из этих групп нужно хранить более кастомные данные.

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

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

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

Когда нужно использовать конструктор

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