Click here to Skip to main content
12,400,556 members (58,993 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

2K views
1 bookmarked
Posted

Emulating final

, 25 Feb 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
CodeProject 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. In the above code, with the FINAL macro, class B privately inherits from class make_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


License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gabor Fekete
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 26 Feb 2014
Article Copyright 2014 by Gabor Fekete
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid