C++11 introduced the keyword final
to forbid future overrides or to prohibit inheritance. The most common example where one may use it is for the case of classes that are not intended to be used as base classes (have e.g. non-virtual destructors). However, sometime we may want to have an is-implemented-in-terms-of relation between two classes (i.e. private
inheritance), and not a is-a relationship (public
inheritance). However, final
prohibits both types of inheritance.
My question is the following: is there any way of allowing private
inheritance but forbidding public
inheritance (probably not directly, but at least can we "simulate" it)? In this case, there won't be any issues even if we use a class with a non-virtual destructor, as we cannot use directly the derived class via a pointer to base, so we should be fine.
I am thinking of a code like this:
class Base /*final*/ {}; // making it final prohibits both private and public inheritance
class PrivateDerived: private Base{}; // this should work
class PublicDerived: public Base{}; // this shouldn't
int main()
{
PrivateDerived prvd;
PublicDerived pubd; // this should not compile
// Base* pBase = new PrivateDerived; // doesn't work, so we are ok
}
public inheritance makes public members of the base class public in the derived class, and the protected members of the base class remain protected in the derived class. protected inheritance makes the public and protected members of the base class protected in the derived class.
You need to define it as protected . Protected members are inherited to child classes but are not accessible from the outside world. after inheriting protected members, you can provide public access. then we should avoid to keep personal data in protected access specifier.
The protected members are inherited by the child classes and can access them as its own members. But we can't access these members using the reference of the parent class. We can access protected members only by using child class reference.
Instead, private inheritance refers to the idea of being "implemented in terms of a". The key difference is that whereas public inheritance provides a common interface between two classes, private inheritance does not--rather, it makes all of the public functions of the parent class private in the child class.
Interesting question! If you don't mind giving up the destructor's triviality, I think the following does the job:
#include <type_traits>
template <typename T>
class Base {
protected:
~Base() {
static_assert(!std::is_convertible<T*,Base*>::value, "Invalid use of public inheritance.");
}
};
class Derived : public Base<Derived> {
};
int main() {
Derived d;
}
The code above fails to compile: the static_assert
fires because Derived*
is convertible to Base<Derived>*
. However if you change the inheritance to either protected
or private
then the code compiles.
Unfortunately users can still shoot themselves in the foot:
class Bad : public Base<Derived> {
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With