Является ли базовая рекомендация C35 C35 «Деструктор базового класса должен быть либо publi c и виртуальным, либо защищенным и не виртуальным», не подходящим для классов интерфейса? - PullRequest
3 голосов
/ 23 февраля 2020

Скажем, у меня есть следующий интерфейсный класс для «записи в интерфейсы, а не в реализации»:

class IDrawable
{
public:

    virtual void
    Draw() const = 0;

protected:

    ~IDrawable() = default;
};

Клиенты не должны иметь возможность удалять динамически размещаемые объекты рисования через указатель интерфейса, поэтому IDrawable ' Деструктор s сделан защищенным и не виртуальным, в соответствии с C ++ Core Guideline C .35: деструктор базового класса должен быть либо publi c и виртуальным, либо защищенным и не виртуальным.

Теперь для класса, который реализует этот интерфейс:

class CDrawable : public IDrawable
{
public:

    void
    Draw() const override;
};

Это, конечно, выдает предупреждение:

CDrawable имеет виртуальные функции, но не виртуальный деструктор.

Чтобы решить эту проблему, теперь мы должны добавить виртуальный деструктор к CDrawable. Но похоже на запах кода, когда в производном классе есть виртуальный деструктор, я раньше такого не видел (?) Разве не имеет смысла иметь виртуальный деструктор в IDrawable, что противоречит руководству говорит?

1 Ответ

2 голосов
/ 23 февраля 2020

Технически проблем нет. Ваш CDrawable имеет не виртуальный деструктор c (неявно определенный). Вызов его не вызывает неопределенного поведения, если, конечно, он не вызывается для класса, производного от CDrawable. Если у вас есть только ссылка на IDrawable и вызван ее деструктор, вы бы пропустили уничтожение производного класса (я думаю, что это вызвало UB), но, поскольку он недоступен для общественности, это не проблема.

Да, вы получаете предупреждение. Тем не менее, это предупреждение является лишь указанием на то, что что-то может быть не так. В данном случае это не так.

...