Защищенные невиртуальные деструкторы базового класса

В книге А.Александреску "Стандарты программирования на С++" в 50 совете говорится: "Делайте деструкторы базовых классов открытыми и виртуальными либо защищенными и невиртуальными". Скажите в каких случаях применяются protected невиртуальные деструкторы. В чем польза этого подхода?


Ответы (1 шт):

Автор решения: Harry

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

struct Base
{
    ~Base();
};

struct Derived: public Base
{
    ~Derived();
};


int main()
{
    Base * b = new Derived;
    delete b;
}

Так сказать, угадайте с трех раз, какой деструктор вызовется, и будет ли это верное поведение...

Если же вы делаете деструктор не виртуальным, то защититься от такого неверного использования можно, сделав деструктор ~Base() защищенным - все, такой код вы написать просто не сможете.

Только

struct Base
{
protected:
    ~Base() { cout << "~Base\n"; };
};

struct Derived: public Base
{
    ~Derived()  { cout << "~Derived\n"; };
};


int main()
{
    Derived * b = new Derived;
    delete b;
}

Но, как и в других вопросах C++ - если бы какой-то совет был не советом, а жестким требованием - он вошел бы в стандарт как запрет. Так что у вас есть выбор, как поступать, и всегда есть ситуации, когда лучше поступить вопреки совету.

→ Ссылка