Sealing a C++ Class

Unlike C#, C++ doesn’t have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism.

The trick is to virtually inherit from a base class where the constructor is private and the sub-class is declared a friend in said base class. If you then try to sub-class the pseudo sealed class the compiler will not be able to synthesize a callable constructor for the virtual base class so instantiation will fail.

It works by making the default constructor of the sealer class private, which means nothing can construct it. We then make the class we want to seal a friend of the sealer class and subclass it with virtual inheritance. As the subclass is a friend of the sealer class it can call the private constructor so we are able to instantiate instances of it. Since we virtually inherited the sealer class and since in C++ the top most sub-class of an inheritance tree always called the base classes constructor directly the fact that this constructor is inaccessible means the compiler will produce an error. Voila, we have sealed the class to prevent it being sub-classed.

The following code example uses a macro called SEALED, which takes care of creating a virtual base class and making the real class virtually derive from it.

#define SEALED(className)
	className ## Sealer
		{
			private: className ## Sealer(){};
			friend class className;
		};
		class className : virtual private className ## Sealer

class SEALED(MyClass) {};

class MyClassDisallowed : public MyClass {};

int main()
{
	// Perfectly legal construction
	MyClass myClass;

	// Illegal construction, super-class is sealed
	MyClassDisallowed myClassDisallowed;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s