Prevent class inheritance in C++
Recently one of my friend asked me how to prevent class inheritance in C++. He wanted the compilation to fail.
I was thinking about it and found 3 answers. Not sure which is the best one.
1) Private Constructor(s)
class CBase
{
public:
static CBase* CreateInstance()
{
CBase* b1 = new CBase();
return b1;
}
private:
CBase() { }
CBase(CBase3) { }
CBase& operator=(CBase&) { }
};
2) Using CSealed
base class, private ctor & virtual inheritance
class CSealed
{
private:
CSealed() {
}
friend class CBase;
};
class CBase : virtual CSealed
{
public:
CBase() {
}
};
3) Using a CSealed
base class, protected ctor & virtual inheritance
class CSealed
{
protected:
CSealed() {
}
};
class CBase : virtual CSealed
{
public:
CBase() {
}
};
All the above methods make sure that CBase
class cannot be inherited further.
My Question is:
-
Which is the best method ? Any other methods available ?
-
Method 2 & 3 will not work unless the
CSealed
class is inherited virutally. Why is that ? Does it have anything to do with vdisp ptr ??
PS:
The above program was compiled in MS C++ compiler (Visual Studio). reference : http://www.codeguru.com/forum/archive/index.php/t-321146.html
As of C++11, you can add the final keyword to your class, eg
class CBase final
{
...
The main reason I can see for wanting to do this (and the reason I came looking for this question) is to mark a class as non subclassable so you can safely use a non-virtual destructor and avoid a vtable altogether.
You can't prevent inheritance (before C++11's final
keyword) - you can only prevent instantiation of inherited classes. In other words, there is no way of preventing:
class A { ... };
class B : public A { ... };
The best you can do is prevent objects of type B from being instantiated. That being the case, I suggest you take kts's advice and document the fact that A (or whatever) is not intended to be used for inheritance, give it a non-virtual destructor, and no other virtual functions, and leave it at that.
You are going through contortions to prevent further subclassing. Why? Document the fact that the class isn't extensible and make the dtor non-virtual. In the spirit of c, if someone really wants to ignore the way you intended this to be used why stop them? (I never saw the point of final
classes/methods in java either).
//Note: this class is not designed to be extended. (Hence the non-virtual dtor)
struct DontExtened
{
DontExtened();
/*NOT VIRTUAL*/
~DontExtened();
...
};