TITLE: renaming virtual functions for multiple inheritance (Newsgroups: comp.lang.c++.moderated, 27 Jul 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 #39: Multiple Inheritance - Part III Difficulty: 4 / 10 _______________________________________________________ >Demonstrate how to write a class D, publicly derived >from both B1 and B2, which overrides both ReadBufs >independently to do different things. Here's the naive attempt that won't work: class D : public B1, public B2 { public: int ReadBuf( const char* ); // overrides both B1::ReadBuf and B2::ReadBuf }; This overrides BOTH functions with the same implementation, whereas the point of the question was to override the two functions to do different things. You can't just "switch" behaviours inside this D::ReadBuf depending which way it gets called, either, because once you're inside D::ReadBuf there's no way of telling which base interface was used (if any). Renaming Virtual Functions -------------------------- If the two inherited functions had different signatures, there would be no problem: We would just override them independently as usual. The trick, then, is to somehow change the signature of at least one of the two inherited functions. The way to change a base class function's signature is to create an intermediate class which derives from the base class, declares a new virtual function, and overrides the inherited version to call the new function. The following code renames both inherited functions (for readability only, since it's sufficient to simply rename one): class D1 : public B1 { public: virtual int ReadBufB1( const char* p ) = 0; int ReadBuf( const char* p ) // override inherited { return ReadBufB1( p ); } // to call new func }; class D2 : public B2 { public: virtual int ReadBufB2( const char* p ) = 0; int ReadBuf( const char* p ) // override inherited { return ReadBufB2( p ); } // to call new func }; D1 and D2 may also need to duplicate constructors of B1 and B2 so that D can invoke them, but that's it. D1 and D2 are abstract classes, so they do NOT need to duplicate any other B1/B2 functions or operators, such as assignment operators. Now we can simply write: class D : public D1, public D2 { public: int ReadBufB1( const char* ); int ReadBufB2( const char* ); }; Derived classes only need to know that they must not further override ReadBuf itself.