vaughan@puma.cad.mcc.com (Paul Vaughan) (09/21/89)
This is partly a followup to Craig Zarmer's excellent description of the problem of extending libraries. The problem arises when many library classes inherit non-virtually from a library base class, and one wants to create new versions of these derived classes based on an extended version of that base class, without modifying the library source. For instance, in the example below, I might want to have a list of objects that derive from both LibBase and MyBase (some of which might be MyDerived objects), where the list pointer type allows me to call both foo() from LibBase and bar() from MyBase. Remember that there is a problem if I derive MyDerived from the Bogus class and from LibDerived. MyDerived would get two LibBase components. This can't be helped because LibDerived derives from LibBase non-virtually and that code cannot be changed. I want to know what the informed experts (and opinionated non-experts like me) think of this usage of C++ multiple inheritance. I particularly want to know if the cast is going to work or cause trouble. This example compiles and runs with g++ 1.35.1. #include <stream.h> //----------------------- fixed library code : Hands Off class LibBase { public: LibBase() { cout << "LibBase Constructor\n";}; foo() { cout << "LibBase::foo()\n";}; }; class LibDerived : public LibBase { // one of many public: LibDerived() { cout << "LibDerived Constructor\n";}; }; //------------------------ my extension code : rearrange at will class MyBase { public: MyBase() { cout << "MyBase Constructor\n";}; bar() { cout << "MyBase::bar()\n";}; }; // one for every interesting LibDerived class class MyDerived : public MyBase, public LibDerived { public: MyDerived() { cout << "MyDerived Constructor\n"; }; }; // Bougs is used only to represent things that inherit from both // MyBase and LibBase. // No Bogus objects are ever made and nothing derives from Bogus class Bogus : public MyBase, public LibBase {}; //------------------------- main() { // Although MyDerived (or other similar classes it represents) // does not derive from Bogus, I know that MyDerived inherits from the // same base classes as Bogus. I may assume that it inherits from no // other base classes, but I'm not sure if that is necessary for this // cast to work. Bogus* bogus = (Bogus*) new MyDerived; bogus->foo(); bogus->bar(); } [1.229]puma) lib2 MyBase Constructor LibBase Constructor LibDerived Constructor MyDerived Constructor LibBase::foo() MyBase::bar() Give it a rating: Incredibly useful (donations accepted), Interesting technique, So who cares, but it's guaranteed to work in all implementations, given the assumptions, Dubious at best, An accident waiting to happen, Author deserves a Pox and revocation of programmer's license Also, I'd be obliged if people would people try it in their implementation, regardless of their theoretical answer. Paul Vaughan, MCC CAD Program | ARPA: vaughan@mcc.com | Phone: [512] 338-3639 Box 200195, Austin, TX 78720 | UUCP: ...!cs.utexas.edu!milano!cadillac!vaughan