How to define sealed class in C++?

C++ClassInheritanceDerived ClassSealed

C++ Problem Overview


How to stop the class to be inherited by other class.

C++ Solutions


Solution 1 - C++

C++11 solution

In C++11, you can seal a class by using final keyword in the definition as:

class A final  //note final keyword is used after the class name
{
   //...
};

class B : public A  //error - because class A is marked final (sealed).
{                   //        so A cannot be derived from.
   //...
};

To know the other uses of final, see my answer here:


C++03 solution

Bjarne Stroustrup's code : Can I stop people deriving from my class?

class Usable;
class Usable_lock {
    friend class Usable;
private:
    Usable_lock() {}
    Usable_lock(const Usable_lock&) {}
};

class Usable : public virtual Usable_lock {
public:
    Usable();
    Usable(char*);
};
Usable a;

class DD : public Usable { };

DD dd;  // error: DD::DD() cannot access
        // Usable_lock::Usable_lock(): private  member

Generic_lock

So we can make use of template to make the Usable_lock generic enough to seal any class:

template<class T>
class  Generic_lock 
{
    friend T;
    Generic_lock() {}                     //private
    Generic_lock(const Generic_lock&) {}  //private
};

class Usable : public virtual Generic_lock<Usable>
{
public:
    Usable() {}
};

Usable a; //Okay
class DD : public Usable { };

DD dd; //Not okay!

Solution 2 - C++

There are two ways, the simple cheap, and the correct one. The two answers by @Naveen and @Nawaz deal with the correct one, that requires manual creation of a sealer class for each class that you actually want to seal.

The not fool-proof way, which is used in the adobe libraries is using a templated class for that. The problem is that you cannot declare the template argument as a friend, and that means that you will have to switch from private to the less safe protected:

template <typename T>
class sealer {
protected: sealer() {}
};
class sealed : virtual sealer<sealed> {};

And you can automate it with a macro (I don't remember the exact flavor of the macro in Adobe's code):

#define seal( x ) virtual sealer<x>
class sealed : seal(sealed) 
{};

Now this will catch people that mistakenly try to inherit without knowing that they shouldn't:

class derived : sealed {};
int main() {
   derived d;  // sealer<T>::sealer() is protected within this context
}

But it will not inhibit people that really want to from deriving, as they can gain access to the constructor by deriving from the template themselves:

class derived : sealed, sealer<sealed> {};
int main() {
   derived d;
};

I am not sure whether this will change in C++0x, I think I recall some discussions on whether a class template would be allowed to befriend one of it's arguments, but in a cursory search through the draft I cannot really tell. If that was allowed then this would be a fine generic solution:

template <typename T>
class sealer {
   sealer() {}
   friend class T; // Incorrect in C++03
};

Solution 3 - C++

C++11 adds the ability to prevent inheriting from classes or simply preventing overriding methods in derived classes. This is done with the special identifier final. For example:

class Base final { };

class Derived1 : Base { }; // ill-formed because the class Base has been marked final

or

class Base {
    virtual void f() final;
};
 
class Derived : Base {
    void f(); // ill-formed because the virtual function Base::f has been marked final

Note that final is not a language keyword. It is technically an identifier; it only gains special meaning when used in those specific contexts. In any other location, it can be a valid identifier.

Solution 4 - C++

Based on Bjarne Stroustrup's http://www.stroustrup.com/bs_faq2.html#no-derivation FAQ with small modification without friend keyword usage:

// SEALED CLASS DEFINITIONS
class Usable_lock {
protected:
	Usable_lock() {}
	Usable_lock(const Usable_lock&) {}
};
#define sealed_class private virtual Usable_lock

// SEALED CLASS USAGE EXMAPLES
class UsableLast : sealed_class {
public:
	UsableLast(){}
	UsableLast(char*){}
};
class DD : public UsableLast {};

// TEST CODE
template <class T> T createInstance() {
	return T();
}
int main()
{
	createInstance<UsableLast>();
//	createInstance<DD>();
	return 0;
}

Solution 5 - C++

The following code shows how to define a sealed class in C++/CLI.

class A sealed
{
	//here goes the class code
};

class B : public A
{
};

Now B : cannot inherit from A as it has been declared as 'sealed'. Also a detailed explanation about sealed keyword can be found here http://msdn.microsoft.com/en-us/library/0w2w91tf.aspx

Update: Added C++/CLI , also other answers have shown the latest C++11 way of achieving the same using final keyword.

Solution 6 - C++

You cannot. C++ is not Java or C#. And also there is no point, ever, IMHO.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShashiView Question on Stackoverflow
Solution 1 - C++NawazView Answer on Stackoverflow
Solution 2 - C++David Rodríguez - dribeasView Answer on Stackoverflow
Solution 3 - C++AzPView Answer on Stackoverflow
Solution 4 - C++Konstantin BurlachenkoView Answer on Stackoverflow
Solution 5 - C++Krishna OzaView Answer on Stackoverflow
Solution 6 - C++wilxView Answer on Stackoverflow