We have a restriction that a class cannot act as a base-class for more than 7 classes. Is there a way to enforce the above rule at compile-time?
I am aware of Andrew Koenig's Usable_Lock technique to prevent a class from being inherited but it would fail only when we try to instantiate the class. Can this not be done when deriving itself?
The base-class is allowed to know who are its children. So i guess we can declare a combination of friend classes and encapsulate them to enforce this rule. Suppose we try something like this
class AA {
friend class BB;
private:
AA() {}
~AA() {}
};
class BB : public AA {
};
class CC : public AA
{};
The derivation of class CC would generate a compiler warning abt inaccessible dtor. We can then flag such warnings as errors using compiler tweaks (like flag all warnings as errors), but i would not like to rely on such techniques.
Another way, but to me looks rather clumsy is:-
class B;
class InheritanceRule{
class A {
public:
A() {}
~A() {}
};
friend class B;
};
class B {
public:
class C : public InheritanceRule::A
{};
};
class D : public InheritanceRule::A{};
The derivation of class D will be flagged as a compiler error, meaning all the classes to be derived should be derived inside class B. This will allow atleast an inspection of the number of classes derived from class A but would not prevent anyone from adding more.
Anyone here who has a way of doing it ? Better still if the base-class need not know who are its children.
NOTE: The class which acts as a base-class can itself be instantiated (it is not abstract).
Thanks in advance,
EDIT-1: As per Comment from jon.h, a slight modification
// create a template class without a body, so all uses of it fail
template < typename D>
class AllowedInheritance;
class Derived; // forward declaration
// but allow Derived by explicit specialization
template<>
class AllowedInheritance< Derived> {};
template<class T>
class Base : private AllowedInheritance<T> {};
// privately inherit Derived from that explicit specialization
class Derived : public Base<Derived> {};
// Do the same with class Fail Error
// it has no explicit specialization, so it causes a compiler error
class Fail : public Base<Fail> {}; // this is error
int main()
{
Derived d;
return 0;
}