Amazon Interview Question
Software Engineer / DevelopersThe Need for a Final Class
Useful for a class without a virtual destructor. Suppose you are making a class that doesn't have a virtual destructor; it may contain some dynamically allocated object. Now, if anyone inherits a class from it and creates the object of the derived class dynamically, it will clearly create a resource leak although the compiler will not complain about this.
class B {
. . .
};
class D : public B {
. . .
};
B* pB = new D;
delete pB; // resource leak
Approch for making a Final Class
1.Make constructor private, and make a static function 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.
2.Make destructor private instead of making a constructor because there can be only one destructor in the class.Problem with this approach is that the creation of an object is not possible on the stack; the object must be created on the 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 a resource leak if the user of this class forgets to delete the object of this class from the heap when it is not needed.
3.The diamond problem You solve that problem by making a virtual base class and inheriting intermediate classes virtually. The object of most drive classes (whose object is created) directly calls the constructor of the virtual base class. So, we resolve the diamond problem because now the most drive class (Bottom, in the case of diamond problem) directly calls the most base class (Top, in the diamond problem) constructor, and now there is only a single copy of Top most class.
Inherit FinalClass virtually from the Temp class and make Temp a virtual base class. Now, whenever anyone attempts to inherit a class from FinalClass and make an object of it, its constructor tries to call the constructor of Temp. But the constructor of Temp is private, so the compiler complains about this and it gives an error during the compilation because your derived class is not a friend of Temp. But, when you create an object of FinalClass, its constructor can call the Temp's constructor because FinalClass is a friend of Temp. So, here is the final version of the final class, which can also be created on the stack, not only on the heap.
class Temp
{
private:
~Temp() { };
friend class FinalClass;
};
class FinalClass : virtual public Temp
{
. . .
};
Generalized Form
template <typename T>
class MakeFinal
{
private:
~MakeFinal() { };
friend T;
};
Don't forget to virtually inherit your final class from this class to make sure this class becomes a virtual base class. And, pass your final class name as a template parameter so your class becomes a friend of this and can call the constructor of this class.
class FinalClass : virtual public MakeFinal<FinalClass>
{
};
simple - make its constructor private :)
- aks June 01, 2008