Spec-Zone.ru › C++

Абстрактный класс

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

Синтаксис

Чистая виртуальная функция — это виртуальная функция, декларатор которой имеет следующий синтаксис:

декларатор virt-specifier (необязательно) = 0

Здесь последовательность = 0 известна как чистый спецификатор, и появляется либо сразу после декларатора, либо после необязательного virt-specifier (override или final).

чистый спецификатор не может появляться в определении члена функции или в декларации friend.

struct Base
{
    virtual int g();
    virtual ~Base() {}
};
 
struct A : Base
{
    // OK: declares three member virtual functions, two of them pure
    virtual int f() = 0, g() override = 0, h();
 
    // OK: destructor can be pure too
    ~A() = 0;
 
    // Error: pure-specifier on a function definition
    virtual int b() = 0 {}
};

Абстрактный класс — это класс, который определяет или наследует по меньшей мере одну функцию, для которой окончательный переопределитель является чисто виртуальным.

Объяснение

Абстрактные классы используются для представления общих понятий (например, Фигура, Животное), которые могут использоваться в качестве базовых классов для конкретных классов (например, Круг, Собака).

Нельзя создать объекты абстрактного класса (за исключением базовых подобъектов класса, производного от него), и нельзя объявлять нестатические члены данных, тип которых — абстрактный класс.

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

Можно объявить указатели и ссылки на абстрактный класс.

struct Abstract
{
    virtual void f() = 0;  // pure virtual
}; // "Abstract" is abstract
 
struct Concrete : Abstract
{
    void f() override {}   // non-pure virtual
    virtual void g();      // non-pure virtual
}; // "Concrete" is non-abstract
 
struct Abstract2 : Concrete
{
    void g() override = 0; // pure virtual overrider
}; // "Abstract2" is abstract
 
int main()
{
    // Abstract a;   // Error: abstract class
    Concrete b;      // OK
    Abstract& a = b; // OK to reference abstract base
    a.f();           // virtual dispatch to Concrete::f()
    // Abstract2 a2; // Error: abstract class (final overrider of g() is pure)
}

Определение чистой виртуальной функции может быть предоставлено (и должно быть предоставлено, если чистая виртуальная функция является деструктором): функции членов производного класса могут свободно вызывать чистую виртуальную функцию абстрактного базового класса с помощью квалифицированного идентификатора функции. Это определение должно быть предоставлено вне тела класса (синтаксис объявления функции не позволяет одновременно использовать чистый спецификатор = 0 и тело функции).

Вызов виртуальной функции чисто виртуальной функции из конструктора или деструктора абстрактного класса является неопределённым поведением (независимо от того, есть ли у неё определение или нет).

struct Abstract
{
    virtual void f() = 0; // pure virtual
    virtual void g() {}   // non-pure virtual
 
    ~Abstract()
    {
        g();           // OK: calls Abstract::g()
        // f();        // undefined behavior
        Abstract::f(); // OK: non-virtual call
    }
};
 
// definition of the pure virtual function
void Abstract::f()
{
    std::cout << "A::f()\n";
}
 
struct Concrete : Abstract
{
    void f() override
    {
        Abstract::f(); // OK: calls pure virtual function
    }
 
    void g() override {}
 
    ~Concrete()
    {
        g(); // OK: calls Concrete::g()
        f(); // OK: calls Concrete::f()
    }
};

Отчеты об ошибках

Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применено к Поведение, как опубликовано Корректное поведение
CWG 390 C++98 деструктор с неопределённой чистой виртуальной функцией может быть вызван в этом случае требуется определение
CWG 2153 C++98 чистый спецификатор мог появляться в декларациях friend запрещено

См. также

  • virtual

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/abstract_class

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API