Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

2.4. Абстрактные классы и чисто виртуальные функции кратко

Лекция



Привет, сегодня поговорим про абстрактные классы, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое абстрактные классы, чисто виртуальные методы , настоятельно рекомендую прочитать все из категории С++ (C plus plus).

Абстрактным называется класс, в котором есть хотя бы одна чистая (пустая) виртуальная функция.Чистой виртуальной называется компонентная функция, которая имеет следующее определение:virtual тип имя_функции(список_формальных_параметров) = 0;Чистая виртуальная функция ничего не делает и недоступна для вызовов. Ее назначение – служить основой для подменяющих ее функций в производных классах. Абстрактный класс может использоваться только в качестве базового для производных классов.Механизм абстрактных классов разработан для представления общих понятий, которые в дальнейшем предполагается конкретизировать. При этом построение иерархии классов выполняется по следующей схеме. Во главе иерархии стоит абстрактный базовый класс. Он используется для наследования интерфейса. Производные классы будут конкретизировать и реализовать этот интерфейс. В абстрактном классе объявлены чистые виртуальные функции, которые по сути есть абстрактные методы.

Пример 2.4.1

class Base{

public:
Base();                     // конструктор по умолчанию
Base(const Base&);  // конструктор копирования
virtual ~Base();     // виртуальный деструктор
virtual void Show()=0;     //  чистая виртуальная функция
// другие чистые виртуальные функции

protected:
// защищенные члены класса

private:
// часто остается пустым, иначе будет мешать будущим разработкам

};

class Derived: virtual public Base{
public:
Derived();                       // конструктор по умолчанию
Derived(const Derived&);         // конструктор копирования
Derived(параметры);              // конструктор с параметрами
virtual ~Derived();              // виртуальный деструктор
void Show();                     // переопределенная виртуальная функция
// другие переопределенные виртуальные функции
Derived& operator=(const Derived&);       // перегруженная операция присваивания
// ее смысл будет понятен после прочтения главы 3
// другие перегруженные операции

protected:
// используется вместо private, если ожидается наследование

private:
// используется для деталей реализации

};

По сравнению с обычными классами абстрактные классы пользуются “ограниченными правам”. Об этом говорит сайт https://intellect.icu . А именно:

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

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

Пример 2.4.2

Сформируем односвязный список, содержащий объекты разных классов, производных от одного абстрактного класса.

2.4. Абстрактные классы и чисто виртуальные функции

2.4. Абстрактные классы и чисто виртуальные функции

2.4. Абстрактные классы и чисто виртуальные функции

2.4. Абстрактные классы и чисто виртуальные функции

2.4. Абстрактные классы и чисто виртуальные функции

2.4. Абстрактные классы и чисто виртуальные функции

Чисто виртуальные функции и абстрактные классы

Когда виртуальная функция не переопределена в производном классе, то при вызове ее в объекте производного класса вызывается версия из базового класса. Однако во многих случаях невоз­можно ввести содержательное определение виртуальной функции в базовом классе. Например, при объявлении базового класса figure в предыдущем примере определение функции show_area() не несет никакого содержания. Она не вычисляет и не выводит на экран площадь объекта какого- либо типа. Имеется два способа действий в подобной ситуации. Первый, подобно предыдущему примеру, заключается в выводе какого-нибудь предупреждающего сообщения. Хотя такой подход полезен в некоторых ситуациях, он не является универсальным. Могут быть такие виртуальные функции, которые обязательно должны быть определены в производных классах, без чего эти производные классы не будут иметь никакого значения. Например, класс triangle бесполезен, если не определена функция show_агеа(). В таких случаях необходим метод, гарантирующий, что производные классы действительно определят все необходимые функции. Язык С++ предлагает в качестве решения этой проблемы чисто виртуальные функции.

Чисто виртуальная функция (pure virtual function) является функцией, которая объявляется в базовом классе, но не имеет в нем определения. Поскольку она не имеет определения, то есть
тела в этом базовом классе, то всякий производный класс обязан иметь свою собственную версию определения. Для объявления чисто виртуальной функции используется следующая общая форма:



virtual тип имя_функции(список параметров) = 0;

Здесь тип обозначает тип возвращаемого значения, а имя_функции является именем функции. На­пример, следующая версия функции show_area() класса figure является чисто виртуальной функцией.


class figure {
double х, у;
public:
void set_dim(double i, double j=0) {
x = i;
y = j;
}
virtual void show_area() = 0; // чисто виртуальная
};

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

/* Данная программа не компилируется, поскольку класс circle не переопределил show_агеа() */
#include <iostream.h>
class figure {
protected:
double x, y;
public:
void set_dim(double i, double j) {
x = i;
у = j;
}
virtual void show_area() = 0; // pure
};
class triangle: public figure {
public:
void show_area() {
cout << "Triangle with height ";
cout << x << " and base " << y;
cout << " has an area of ";
cout << x * 0.5 * у << ". \ n";
}
};
class square: public figure {
public:
void show_area() {
cout << "Square with dimensions ";
cout << x << "x" << y;
cout << " has an area of ";
cout << x * у << " . \n";
}
};
class circle: public figure {
// определение show_area() отсутствует и потому выдается ошибка
};
int main ( )
{
figure *р; // создание указателя базового типа
circle с; // попытка создания объекта типа circle - ОШИБКА
triangle t; // создание объектов порожденных типов
square s;
p = &t;
p->set_dim(10.0, 5.0);
p->show_area ();
p = &s;
p->set_dim(10.0, 5.0);
p->show_area();
return 0;
}

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

В общем, мой друг ты одолел чтение этой статьи об абстрактные классы. Работы впереди у тебя будет много. Смело пиши комментарии, развивайся и счастье окажется в твоих руках. Надеюсь, что теперь ты понял что такое абстрактные классы, чисто виртуальные методы и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории С++ (C plus plus)

Из статьи мы узнали кратко, но содержательно про абстрактные классы
создано: 2015-12-20
обновлено: 2021-03-13
132407



Рейтиг 8 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

С++ (C plus plus)

Термины: С++ (C plus plus)