There are two ways you can have an inner class of a base class
First, to make the constructors private, for example:
struct Sub1; struct Sub2; struct Base { virtual ~Base() = default; private: Base() = default; Base(const Base&) = default; friend struct Sub1; friend struct Sub2; }; struct Sub1 : protected Base {};
The second way is to declare a base class in an anonymous namespace:
namespace { struct Base{}; } struct Sub : Base {};
Now all classes in one translation unit can use Base , but other classes do not know that it exists.
This method is often less desirable since derived classes can be used as incomplete types (forwarded).
source share