There's a trick you can use in C++03 to avoid needing a factory:
struct Final;
struct FinalHelper {
friend struct Final;
private:
FinalHelper() {}
~FinalHelper() {}
};
struct Final : private virtual FinalHelper {
Final() {}
};
This doesn't actually prevent someone from using Final
as a base class, but it does prevent them from constructing or destroying their derived class. The reason is that the most-derived class is responsible for constructing and destroying virtual bases, but the constructor and destructor of FinalHelper
are not accessible in the most-derived class unless it is Final
.
Of course this probably has a runtime memory cost (for the virtual base).
Usually such tricks are pointless. C++ relies on programmers reading the documentation, so a built-in final
mechanism is fine, but you don't want to incur either a runtime cost (for the virtual base) or a usability cost (for the factory function, since the type can only be copy-constructed, which for example affects its use with some container member functions) just to enforce documentation.
So, types should document whether or not they are intended for use as base classes, and users who ignore that documentation only have themselves to blame.