The solution is pretty bad, it can be improved with CRTP (adobe does this), but it will not be a complete solution. The problem with your code is that another programmer who does not want to break your contract (she is a good person), but does not know that she should not leave your class, may want to block others from her own class:
class YourSealedClass : private virtual final {}; class HerSealedClass : public YourSealedClass, private virtual final { };
Please note that there is not even malicious intent, and the contract is violated. Improvement with CRTP will be:
template <typename T> class seal { protected: seal(){} ~seal(){} }; class YourSealedClass : private virtual seal<YourSealedClass> {};
This will catch the previous error, as its code will look like this:
class HerSealedClass : public YourSealedClass, private virtual seal<HerSealedClass> {};
And since it does not inherit from seal<YourSealedClass> , the compiler will catch up with it.
The problem with this approach is that it does not block the stubborn (or malicious) programmer:
class MalignClass : public YourSealedClass, private virtual seal<YourSealedClass> {};
To become a child of the compaction class and as such gain access to your own class.
In C ++ 0x, I believe (I will have to double-check it) that they will raise the restriction that the template cannot make friends with the template argument, and this will be a good step in the generic type solution for the class sealant:
template <typename T> class seal { friend class T;
The advantage of this approach (currently not available) is that since the constructor and destructors are private, friends can instantiate the type. Since you use CRTP to inherit a specific instance that passes its own type as an argument, you tell the compiler that only you can actually create an instance of your base, and all parts fall right into place.