Interfaces
I.25
Предпочитайте пустые абстрактные классы в качестве интерфейсов иерархиям классов
Причина
Абстрактные классы, которые пусты (не имеют нестатических данных-членов), с большей вероятностью будут стабильными, чем базовые классы с состоянием.
Пример (плохой)
Вы наверняка знали, что Shape появится где-нибудь :-)
class Shape { // плохо: интерфейсный класс нагружен данными
public:
Point center() const { return c; }
virtual void draw() const;
virtual void rotate(int);
// ...
private:
Point c;
vector<Point> outline;
Color col;
};
Это заставит каждый производный класс вычислять центр — даже если это нетривиально и центр никогда не используется. Аналогично, не каждая Shape имеет Color, и многие Shape лучше всего представляются без контура, определённого как последовательность Point. Использование абстрактного класса лучше:
class Shape { // лучше: Shape — это чистый интерфейс
public:
virtual Point center() const = 0; // чистые виртуальные функции
virtual void draw() const = 0;
virtual void rotate(int) = 0;
// ...
// ... нет данных-членов ...
// ...
virtual ~Shape() = default;
};
Контроль
(Простой) Предупреждать, если указатель/ссылка на класс C присваивается указателю/ссылке на базовый класс C, и базовый класс содержит данные-члены.