TITLE: controlled polymorphism (Newsgroups: comp.lang.c++.moderated, 3 Aug 98) AUTHOR: herbs@cntc.com (Herb Sutter) .--------------------------------------------------------------------. | Guru of the Week problems and solutions are posted regularly on | | news:comp.lang.c++.moderated. For past problems and solutions | | see the GotW archive at http://www.cntc.com. | | Is there a topic you'd like to see covered? mailto:herbs@cntc.com | `--------------------------------------------------------------------' _______________________________________________________ GotW #40: Controlled Polymorphism Difficulty: 8 / 10 _______________________________________________________ >Consider the following code: > > class Base { > public: > virtual void VirtFunc(); > // ... > }; > > class Derived : public Base { > public: > void VirtFunc(); > // ... > }; > > void SomeFunc( const Base& ); The reason why all code can use Derived objects polymorphically where a Base is expected is because Derived inherits publicly from Base (no surprises here). If instead Derived inherited privately from Base, then "almost" no code could use Deriveds polymorphically as Bases. The reason for the "almost" is that code with access to the private parts of Derived CAN access the private base classes of Derived and can therefore use Deriveds polymorphically in place of Bases. Normally, only the member functions of Derived have such access. However, we can use "friend" to extend similar access to other outside code. Putting the pieces together, we get: >There are two other functions. The goal is to allow >f1 to use Derived object polymorphically where a Base >is expected, yet prevent all other functions (including >f2) from doing so. > > void f1() { > Derived d; > SomeFunc( d ); // works, OK > } > > void f2() { > Derived d; > SomeFunc( d ); // works, but we want to prevent this > } > >Demonstrate how to achieve this effect. The answer is to write: class Derived : private Base { public: void VirtFunc(); // ... friend void f1(); }; This solves the problem cleanly, although it does give f1 greater access than f1 had in the original version.