NOTE: Every post ends with "END OF POST". If you don't see it then open the full post in a separate page!

Emulating final


Emulating the final keyword of C++11 for disallowing inheritance

Here is a way to emulate the “final” feature of C++11 for marking classes non-inheritable. This works with C++98.

// Definition:
namespace xxx_internal
{
  template<typename T>
  class make_final {
  private:
    make_final() {}
    friend T;
  };
}
#define FINAL(T) virtual xxx_internal::make_final<T>

// Usage example:
class A {};
class B : public A, FINAL(B) {};
class C : public B {};
int main()
{
    B b;
    C c;
    return 0;
}

In the above code, with the FINAL macro, class B privately inherits from class make_final. This means that class B is “implemented in terms of” class make_final but “it is not” a class make_final.
Class B inherits also virtually from make_final. This means that if some other class (e.g. class C) tries to inherit (directly or indirectly) from class B, then this inheriting class must call a constructor of make_final (due to virtual inheritance).
So, if we make the constructors of make_final private, then class C cannot call them and we get a compilation error. This makes inheritance from B impossible, thus B is “final”.
Also, we still want B to be usable on its own so, we mark it as a friend of make_final. This way B can call the private constructor of make_final, but nobody else can.

The above example code gives the following output (GNU GCC version 4.8.1):

$ g++ main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
main.cpp: In constructor 'C::C()':
main.cpp:6:5: error: 'xxx_do_not_use::make_final<T>::make_final() [with T = B]' is private
     make_final() {}
     ^
main.cpp:14:7: error: within this context
 class C : public B {};
       ^
main.cpp: In function 'int main()':
main.cpp:18:7: note: synthesized method 'C::C()' first required here 
     C c;
       ^

END OF POST

Advertisements


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