Deprecated: Function set_magic_quotes_runtime() is deprecated in /customers/c/c/b/jogear.net/httpd.www/textpattern/lib/txplib_db.php on line 14 jogear.net: Making a C++ class sealed
Skip to Content »

 Making a C++ class sealed

  • 2008-05-14 16:54

Yesterday, while flying around looking for ideas on how to solve a particular Win32 intricacy, I landed, as so often before, in an old MSDN Magazine article by Paul DiLascia1.

The article was irrelevant to my actual quest, but I found an interesting piece of code in it, namely how to make a C++ class sealed in much the same way that you can do with the sealed keyword on a class in C#, i.e., making the class impossible to inherit from.

Paul shows several approaches and ends with this version, which overcomes all described drawbacks of the first attempts (N.B. The class names are mine; Paul used MakeSealed and MyClass):

class Sealed
{
private:
    Sealed() { }

    friend class ConcreteSealed;
};

class ConcreteSealed : virtual Sealed
{
};

Paul describes this solution:

Now nobody can create an instance of Sealed except ConcreteSealed, which is its friend. You can create an instance of ConcreteSealed on the stack, but you can’t derive from ConcreteSealed. You can use Sealed to make other classes sealed, but you have to add them as friends. ConcreteSealed uses Sealed as a virtual base class so you don’t run into problems if you use multiple inheritance.

I have a slight problem with the non-generic nature of the … but you have to add them as friends. part, so I touched it up a bit and made Sealed a class template:

template <typename TConcreteSealed>
class Sealed
{
private:
    Sealed() { }

    friend typename TConcreteSealed;
};

class ConcreteSealed : virtual Sealed<ConcreteSealed>
{
};

This piece of code verifies the correctness of the above assumptions:

class NotSealed : public ConcreteSealed
{
};

int wmain(int, wchar_t*[])
{
    ConcreteSealed cs1;
    ConcreteSealed* cs2 = new ConcreteSealed;

    NotSealed ns1;
    NotSealed* ns2 = new NotSealed;
}

Above, the two first instantiations of ConcreteSealed compile, but the two last instantiations of NotSealed do not compile. Which feels quite good. I might even end up using this. Real soon now.

1 MSDN Magazine, C++ Q&A, List View Mode, SetForegroundWindow, and Class Protection by Paul DiLascia