13 Derived classes [class.derived]

13.4 Abstract classes [class.abstract]

[ Note: Механизм абстрактного класса поддерживает понятие общего понятия, такого как a shape, из которого фактически могут использоваться только более конкретные варианты, такие как circle и square. Абстрактный класс также можно использовать для определения интерфейса, для которого производные классы предоставляют множество реализаций. ]end note

An abstract class - это класс, который может использоваться только как базовый класс какого-либо другого класса; никакие объекты абстрактного класса не могут быть созданы, кроме как подобъекты класса, производного от него. Класс является абстрактным, если в нем есть хотя бы один pure virtual function. [ Note: Такая функция может быть унаследована: см. Ниже. ] Виртуальная функция указывается с помощью символа a в объявлении функции в определении класса. Чисто виртуальная функция должна быть определена только тогда , когда вызываются с, или как будто с ( ), то синтаксис ( ). [end note pure pure-specifier[class.dtor]qualified-id[expr.prim]Example:

class point { /* ... */ };
class shape {                   // abstract class
  point center;
public:
  point where() { return center; }
  void move(point p) { center=p; draw(); }
  virtual void rotate(int) = 0; // pure virtual
  virtual void draw() = 0;      // pure virtual
};

end example] [ Note: Объявление функции не может содержать одновременно pure-specifier и определение ] [end noteExample:

struct C {
  virtual void f() = 0 { };     // ill-formed
};

end example]

Абстрактный класс не должен использоваться как тип параметра, как тип возвращаемого значения функции или как тип явного преобразования. Можно объявить указатели и ссылки на абстрактный класс. [Example:

shape x;                        // error: object of abstract class
shape* p;                       // OK
shape f();                      // error
void g(shape);                  // error
shape& h(shape&);               // OK

end example]

Класс является абстрактным, если он содержит или наследует хотя бы одну чистую виртуальную функцию, для которой последний переопределитель является чисто виртуальной. [Example:

class ab_circle : public shape {
  int radius;
public:
  void rotate(int) { }
  // ab_­circle​::​draw() is a pure virtual
};

Поскольку shape​::​draw() это чистая виртуальная функция,ab_­circle​::​draw() по умолчанию это чистая виртуальная функция . Альтернативная декларация,

class circle : public shape {
  int radius;
public:
  void rotate(int) { }
  void draw();                  // a definition is required somewhere
};

сделает класс circle неабстрактным, и circle​::​draw() должно быть дано определение. ]end example

[ Note: Абстрактный класс может быть производным от класса, который не является абстрактным, а чистая виртуальная функция может переопределить виртуальную функцию, которая не является чистой. ]end note

Функции-члены могут быть вызваны из конструктора (или деструктора) абстрактного класса; эффект преобразования a virtual call в чистую виртуальную функцию прямо или косвенно для объекта, создаваемого (или уничтожаемого) из такого конструктора (или деструктора), не определен.