TITLE: non-derivable classes (Source: comp.lang.c++.moderated, 15 May 2001) ALEXANDRESCU: Andrei Alexandrescu In CUJ on May 2001, Shanker Chandrabose gives a great tip on making classes non-derivable. It's very strange that until now everybody used to go for the friend-based solution: class NonDerivableHelper { NonDerivableHelper() {} friend class NonDerivable; }; class NonDerivable : private virtual NonDerivableHelper { ... your code here ... }; This idiom was discussed a number of times around here. People agree it's a pity you can't make NonDerivableHelper a library class because friends who are template arguments are not allowed. Anyway, Chandrabose comes with an idiom that doesn't require friend: class NonDerivableHelper { protected: NonDerivableHelper() {} }; class NonDerivable : private virtual NonDerivableHelper { ... your code here ... }; Cool! I wonder if there's any flaw in his idea. Now I think the next step is to put this in a library and to optimize away the virtual inheritance overhead: // library header namespace Private { class NonDerivableHelper { protected: NonDerivableHelper() {} }; } #ifdef NDEBUG #define FINAL_CLASS #else #define FINAL_CLASS : private virtual Private::NonDerivableHelper #endif // application code class NonDerivable FINAL_CLASS { ... your code here ... }; _______________________________________________ cpptips mailing list http://cpptips.hyperformix.com Several people wrote to say that the code recently presented did not prevent deriving from a class. This is true. To fix the code so that it works as expected make two changes as marked below. Now class D1 fails to compile as desired. #define FINAL_CLASS : private virtual Private::NonDerivableHelper namespace Private { class NonDerivableHelper { protected: NonDerivableHelper(int) {} <<<<<<<<< ADDED CTOR ARGUMENT }; } class NonDerivable FINAL_CLASS { int x; public: NonDerivable() : NonDerivableHelper(0) {} <<<<<<<<< PASS A DUMMY VALUE virtual void foo() { printf("In NonDerivable\n"); } }; class D1: public NonDerivable { public: D1() : NonDerivable() {}; virtual void foo() { printf("In D1\n"); NonDerivable::foo(); } }; _______________________________________________ cpptips mailing list http://cpptips.hyperformix.com -----Original Message----- From: cpptips-admin@cpptips.hyperformix.com [mailto:cpptips-admin@cpptips.hyperformix.com] On Behalf Of Allan Clarke Sent: 2001/05/25 Friday 7:43 AM To: cpptips Subject: [cpptips] final class again Several people wrote to say that the code recently presented did not prevent deriving from a class. This is true. To fix the code so that it works as expected make two changes as marked below. Now class D1 fails to compile as desired. #define FINAL_CLASS : private virtual Private::NonDerivableHelper namespace Private { class NonDerivableHelper { protected: NonDerivableHelper(int) {} <<<<<<<<< ADDED CTOR ARGUMENT }; } class NonDerivable FINAL_CLASS { int x; public: NonDerivable() : NonDerivableHelper(0) {} <<<<<<<<< PASS A DUMMY VALUE virtual void foo() { printf("In NonDerivable\n"); } }; class D1: public NonDerivable { public: D1() : NonDerivable() {}; virtual void foo() { printf("In D1\n"); NonDerivable::foo(); } }; _______________________________________________ cpptips mailing list http://cpptips.hyperformix.com