A non-inheritable class

Introduction

It is a common question why we shouldn’t inherit classes from STL classes. The answer of this question is
simple. Big three rule [CLI95]. In other words you should have virtual destructor in a class if you want to make it
a base class. However there aren’t any class in STL which define virtual destructor. Even if you try to inherit a class from STL class
the compiler doesn’t complain about it, but there is a high chance of resource leak in the program. It makes programmers life easy if
the compiler catches as many errors as it can during compilation. So it is nice idea to make a class in such a way that
you can’t inherit class from it, in other words a Final class.

Background

One day during a discussion with one of my friends, who is mostly working on java, we compared the object-oriented features of Java and C++. And he introduced me
to one interesting concept of java called Final class, i.e. a class from which you cant inherit any further class. It was
a totally new concept for me at that time and I liked it because most of the time I wish I could make a class in C++ from which others cant inherit. He asked me to do this in C++ and I start thinking
about it and doing some experimentation. Before further discussion on how we can make it, it is useful to discuss why should we need it.

Why might we need a final class?

One possible scenario, which comes to my mind that would be useful for "Final class" is a class without virtual destructor. Suppose you are making a class, which doesn’t have virtual destructor, and it may contain some dynamically allocated object. Now if any one inherits a class
from it and creates the object of derived class dynamically then it will clearly create resource leak although compiler will not complain about this.

Details of implementing a final class

To make a class final the first solution, which may come in mind, is to make its constructor private. And make static functions to create the objects. But there is one problem in this approach that there may be more than one constructor in the class and you have to make all of them private. There is still a chance that anyone can make another public constructor. Quick fix of this problem is to make destructor private instead of constructor because there can be only one destructor in the class.

The one problem with this approach is that creation of object is not possible on
the stack; object must be created on heap. And now it is the responsibility of the user of this class to destroy this object. Again in this case there is a chance of resource leak if user of this class forgot to delete the object of this class from the heap when it is not needed.

Lets take a look at another approach of making a class final and still make it
in such a way that a client of this class can create its object on stack and not
just on the heap. We all know that when we make one class friend of other then it can create object of that class even its destructor is private. So we can create one temporary class and make its constructor private. And inherit one class from it and also make the derived class friend of it base, because if we didn’t do it then we can’t inherit the class from another class whose constructor or destructor is private.

But when you inherit any class from FinalClass this works fine. Let’s suppose you inherit
derived class from FinalClass. Now when you create the object of
derived class, its constructor is called, which will call the constructor of
FinalClass and FinalClass’s constructor calls the constructor of
Temp because FinalClass is friend of Temp. So everything is normal and our final class is still inheritable in other words, it is not final
as of now.

Before going into final class in more detail, let’s discuss the famous multiple inheritance problem,
or the diamond problem. In that case you solve that problem by making virtual base class and inheriting intermediate classes virtually. But what is the purpose of virtual base class? In fact the object of most
derived class (whose object is created) directly call the constructor of virtual base class. So we resolve the diamond problem, because now the most
derived class (Bottom in case of diamond problem) directly calls the most base class (Top in diamond problem) constructor, and now there is only single copy of Top most class.

We can apply the same technique here. We inherit our FinalClass virtually from
Temp class and make Temp as a virtual base class. Now whenever anyone attempts to inherit class from
FinalClass and make object of it, then its constructor tries to call the constructor of
Temp. But the constructor of Temp is private so compiler complains about this and it gives error during the compilation, because your derived class is not friend of
Temp. Remember friendship is not inherited in the derived class. After all your parent's friends are not your friends and your friends are not friends of your children. But when you create object of
FinalClass then its constructor can call the Temp’s constructor because
FinalClass is friend of Temp. So here is final version of
our final class, which can also be created on stack and not just in the heap.

But what is the case when you have to make more than one final class? You have to write double the classes i.e. if you need N final classes then you have to write 2N classes
because in this method we have one temp class with private constructor and your final class. So you have to write lots of same code again and again. Why not try to take advantage of
a template and try to make a class in such a way that if you inherit any class from that class your class will automatically become
a Final class. The code of such a class is so simple.

Don’t forget to virtually inherit your final class from this class to make sure this class becomes virtual base class. And pass your final class name as a template parameter so your class becomes friend of this and can call the constructor of this class.

class FinalClass : virtualpublic MakeFinal<FinalClass>
{
};

Conclusion

Of course nothing comes without cost. You have to pay the extra bytes to store the information about virtual base class. Most of the compiler implementations uses a pointer to store the information about the virtual base class in case of virtual inheritance. Therefore the size of the object is not just the sum of all the member variable storage allocation but it is greater than you expect. Remember
that this pointer i.e. pointer to virtual base class is different than the
virtual pointer, which is introduced in case of virtual function [LIP96]. This is totally
an implementation issue; C++ standard doesn’t say anything about the mechanism of calling virtual function, virtual pointer and virtual table [ISO98].

Adding only one small class and changing few lines of code makes your program more reliable and reduces the resource leak problems, which could be created
if you didn't use a final class.

Comments and Discussions

/home/comawhite/projects/cxxtutorials/main.cpp:12: error: using template type parameter 'T' after 'class'
/home/comawhite/projects/cxxtutorials/main.cpp:12: error: friend declaration does not name a class or function

I originally posted this on the Borland CPP builder newsgroup, but I thought I would put it here so maybe the person giving me the idea could see it (cut-and-paste of the other post at http://newsgroups.borland.com/cgi-bin/dnewsweb?cmd=article&group=borland.public.cppbuilder.language.cpp&item=21329&utag= ). Any and all comments are appreciated...ta0kira

So I was on "The Code Project" yesterday and saw something veryinteresting. Someone named Zeeshan Amjad came up with a C++version of the java "final" modifier that prevents any otherclasses from being derived from a class that uses it. Since I don't like to post other people's code, here is the site:http://www.codeproject.com/cpp/finalclass.asp?print=true

So I went home to try this out, and I had to add a typedef to getit to work, but it worked. I then split it into 2 classes sothat I would not have to use "virtual" when deriving a class fromit. I put it on a lot of classes and it worked, but I got to atemplate I have that I derived 4 specialized classes from.Instead of putting the "final" on all 4 classes I wanted to putit on the template and allow one more derivation so that anyonecould make a specialized class for the type of template, but thencould not derive any more classes from the specialized class.This idea actually came to me on the way to work today, so Iwrote it out first thing when I got there and compiled and testedit at lunch. So here it is. Hope you like it.Kevin P. Barry (aka ta0kira)

//An additional note is this can be used to finalize a class or allow one more//class to be derived without making it a virtual base class. This keeps you//from forgetting 'virtual' and also reduces potential abuse of the class.

I think potentially you could make 3rd to last, etc., if you feltinclined to do so...ta0kira

And get this error. You did the same mistake in your code which i did. When i compile your code using this online compiler i got the same error message that i got when i compiled my code there. Although most of current compiler compile this code, but it is non standard way. May be it will be allowed in comming C++ Standard.

Interesting article Zeeshan, I haven't considered this problem or a solution for it before now. But I am wondering, why not just make your destructors virtual by default instead of removing the ability of the class to be derived from? I can't see any obvious advantage of disallowing a class to be inherited unless you *have* to keep your destructor non-virtual for some reason? Can anyone suggest a reason?

The design of a class that is safe for inheritance is much harder than the design of one that does not take inheritance into account. It's really hard to inherit from a (nontrivial) class to which you don't have anything but the public API. (In C++, you'd likely be able to see the private members as well, but you may or may not have any clue of how to use them, or how they're used in the base class). If you write a class that is not intended to be inherited, or especially one for which it's not safe to inherit b/c you can identify assumptions that an inheritor would probably make which would be wrong, then it's probably a good idea to make the class final, as an indication that it's not meant to be inherited and you're going to get yourself into trouble if you try.

Of course, the ability to make final classes is no excuse for getting lazy and making a class final just because you don't want to figure out how to make it safe to inherit, if it would really be useful to inherit it. The original author often won't have any idea if it's really useful to inherit a class, so my bias would be to try to make any class safe for inheritance unless it can't be made so with reasonable effort - and then make anything else final.

I have a vague feeling that I may have inherited some of this opinion from Scott Meyers, but I can't remember from which book or exactly what part. I know for certain that I got the idea that designing a class that is safe for inheritence is hard from someone else, though I whole-heartedly agree with it.

Interesting article, although I don't agree with the sentiment that classes should be made finalizable at all - if a developer wants to derive from a class, they should be able to, even if that decision will bite them in the bum later on.