Spec-Zone.ru › C++

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

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

Синтаксис

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

declarator virt-specifier (optional) = 0

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

pure-specifier не может использоваться в определении функции-члена или в объявлении 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 {}
};

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

Пояснение

Абстрактные классы используются для представления общих понятий (например, Shape, Animal), которые могут применяться в качестве базовых классов для конкретных классов (например, Circle, Dog).

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

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

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

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 pure-specifier мог использоваться в объявлениях friend запрещено

См. также

  • virtual

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

Spec-Zone.ru

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