C++ Logo

std-proposals

Advanced search

[std-proposals] Public inheritance with banned conversion to base

From: Dennis Gusev <whyarewestillherejust_at_[hidden]>
Date: Wed, 22 Jan 2025 18:29:38 +0300
If you look up "inheriting from STL containers", the top results from SO
and reddit all mention it being a bad practice since standard containers
aren't designed to be inherited from.

Specifically, they dont have virtual destructors so there's a risk of UB
from deleting through pointer to base.

Also if you override any existing member functions and accidentally pass
your derived class to a function expecting a regular STL container, the
original base class member functions will get called instead(not to mention
potential object slicing).

What if C++ had a way to publicly inherit from a class and also ban base
class conversions to avoid potential usage pitfalls with something like
this:

class Base

{

    public:

    void foo()

    {

        std::println("Base foo");

    }

    void bar()

    {

        std::println("Base bar");

    }

};

class PublicDerived : public Base

{

    public:

    void foo()

    {

        std::println("PublicDerived foo");

    }

};

class ComposedDerived : composed Base // new type of inheritance

{

    public:

    void foo()

    {

        std::println("ComposedDerived foo");

    }

};

void testFoo(Base& val)

{

    val.foo();

}

int main()

{

    PublicDerived publicDerived;

    publicDerived.foo(); // prints "PublicDerived foo"

    publicDerived.bar(); // accessible, prints "Base bar"

    testFoo(publicDerived); // uh oh, prints "Base foo" even though we have
our own foo

    ComposedDerived composedDerived;

    composedDerived.foo(); // prints "ComposedDerived foo"

    composedDerived.bar(); // still accessible, prints "Base bar"

    testFoo(composedDerived) // doesn't compile, conversion to base
forbidden

    return 0;

}

Has anything like this ever been proposed?

Seems like it would address a common use case by making it possible to
extend behavior of classes safely even if they weren't designed to be
inherited from(i.e. no public virtual or protected nonvirtual destructor)

Received on 2025-01-22 15:29:55