Skip to content

Discussion: Make base class destructors protected and non-virtual (always) #2325

@purpleKarrot

Description

@purpleKarrot

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions