Абстрактные классы (C++)
Абстрактные классы используются в качестве обобщенных концепций, на основе которых можно создавать более конкретные производные классы. Невозможно создать объект абстрактного типа класса. Однако можно использовать указатели и ссылки на абстрактные типы классов.
Вы создаете абстрактный класс, объявляя по крайней мере одну чистую виртуальную функцию-член. Это виртуальная функция, объявленная с помощью синтаксиса чистого описателя (= 0
). Классы, производные от абстрактного класса, должны реализовывать чисто виртуальную функцию; в противном случае они также будут абстрактными.
Рассмотрим пример, представленный в функциях Virtual. Класс Account
создан для того, чтобы предоставлять общие функции, но объекты типа Account
имеют слишком общий характер для практического применения. Это означает Account
, что это хороший кандидат для абстрактного класса:
// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
Account( double d ); // Constructor.
virtual double GetBalance(); // Obtain balance.
virtual void PrintBalance() = 0; // Pure virtual function.
private:
double _balance;
};
Единственное различие между этим и предыдущим объявлениями состоит в том, что функция PrintBalance
объявлена со спецификатором чисто виртуальной функции pure (= 0
).
Ограничения на использование абстрактных классов
Абстрактные классы нельзя использовать для:
переменных и данных членов;
типов аргументов;
типов возвращаемых функциями значений;
типов явных преобразований.
Если конструктор абстрактного класса вызывает чистую виртуальную функцию напрямую или косвенно, результат не определен. Однако конструкторы и деструкторы абстрактных классов могут вызывать другие функции-члены.
Определенные чистые виртуальные функции
Чистые виртуальные функции в абстрактных классах можно определить или реализовать. Такие функции можно вызывать только с помощью полного синтаксиса:
abstract-class-name::function-name()
Определенные чистые виртуальные функции полезны при разработке иерархий классов, базовые классы которых включают чистые виртуальные деструкторы. Это связано с тем, что деструкторы базового класса всегда вызываются во время уничтожения объектов. Рассмотрим следующий пример:
// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// It's the simplest possible abstract class.
class base
{
public:
base() {}
// To define the virtual destructor outside the class:
virtual ~base() = 0;
// Microsoft-specific extension to define it inline:
// virtual ~base() = 0 {};
};
base::~base() {} // required if not using Microsoft extension
class derived : public base
{
public:
derived() {}
~derived() {}
};
int main()
{
derived aDerived; // destructor called when it goes out of scope
}
В примере показано, как расширение компилятора Майкрософт позволяет добавлять встроенное определение в чистую виртуальную ~base()
. Его можно также определить за пределами класса с помощью base::~base() {}
.
Когда объект aDerived
выходит из область, вызывается деструктор классаderived
. Компилятор создает код для неявного вызова деструктора класса base
после derived
деструктора. Пустая реализация для чистой виртуальной функции ~base
гарантирует, что для функции существует хотя бы какая-то реализация. Без него компоновщик создает неразрешенную ошибку внешнего символа для неявного вызова.
Примечание.
В предыдущем примере чистая виртуальная функция base::~base
вызывается неявно из derived::~derived
. Кроме того, можно явно вызывать чистые виртуальные функции с помощью полного имени функции-члена. Такие функции должны иметь реализацию, или вызов приводит к ошибке во время связи.
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по