For many years, the guideline was:
A base class destructor should be either public and virtual, or protected and non-virtual
However, with C++26, it can acutally be simplified to:
A base class destructor should be protected and non-virtual
class Base
{
public:
virtual void foo() = 0;
protected:
~Base();
};
class Derived : public Base
{
void foo() override;
};
{
Derived d; // OK
std::polymorphic<Base> p1 = Derived{}; // OK
std::shared_ptr<Base> p2 = std::make_shared<Derived>(); // OK
std::unique_ptr<Base> p3 = std::make_unique<Derived>(); // FAILS to compile, should not be used.
Base* p4 = new Derived; delete p4; // FAILS to compile, should not be used.
}
The simplified guideline is easier to learn, easier to teach, and easier to remember.
For experienced programmers, it requires accepting a new mindset.
For many years, the guideline was:
However, with C++26, it can acutally be simplified to:
The simplified guideline is easier to learn, easier to teach, and easier to remember.
For experienced programmers, it requires accepting a new mindset.