We use this sort of a “trampoline” technique all over our codebase, which is a heavy proponent of the Object Oriented Programming methodology. The below is a hypothetical example of how such a scheme may be used to implement polymorphism and trampoline classes together. Polymorphism is a quite well known concept and hence I don’t need to say much about it. However, I can tell you a bit about trampoline classes. In the example below, “ConcreteClassOne” and “ConcreteClassTwo” are the actual objects which do real work and represent a certain real world object and they may need to receive notifications from other objects. The interfaces for the notifications are represented as “BaseClass” and every concrete object has a member which is a “DerivedClass” which inherits the “BaseClass”. This “DerivedClass” is just a trampoline class which does not do much, it just calls its owner “ConcreteClass” which does all the real work.

The advantage of using a trampoline classes is that you can use it to convert cases where you may have required multiple inheritance into just single inheritance. How? In the example below, lets say you had another “BaseClassTypeTwo” and “ConcreteClassOne” needed to inherit methods of “BaseClassTypeTwo” as well. Without trampoline classes, “ConcreteClassOne” would end up inheriting “BaseClass” and “BaseClassTypeTwo”. However, with trampoline classes, you can just create a new trampoline member for “ConcreteClassOne”, say “DerivedOneTypeTwo”, which singly inherits “BaseClassTypeTwo”, thereby eliminating the need for “ConcreteClassOne” to inherit multiple base classes.

#include <iostream> class BaseClass; class DerivedOne; class DerivedTwo; class ConcreteClassOne; class ConcreteClassTwo; class BaseClass { public: BaseClass() {} virtual void functionOne() {} }; class DerivedOne : public BaseClass { public: DerivedOne( ConcreteClassOne * me ) { me_ = me; } ~DerivedOne() { me_ = 0; } void functionOne(); private: ConcreteClassOne * me_; }; class DerivedTwo : public BaseClass { public: DerivedTwo( ConcreteClassTwo * me ) { me_ = me; } ~DerivedTwo() { me_ = 0; } void functionOne(); private: ConcreteClassTwo * me_; }; class ConcreteClassOne { public: ConcreteClassOne() { trampolineObj_ = new DerivedOne( this ); } ~ConcreteClassOne() { delete trampolineObj_; } DerivedOne * trampoline() { return trampolineObj_; } private: friend class DerivedOne; DerivedOne * trampolineObj_; void functionOne(); }; class ConcreteClassTwo { public: ConcreteClassTwo() { trampolineObj_ = new DerivedTwo( this ); } ~ConcreteClassTwo() { delete trampolineObj_; } DerivedTwo * trampoline() { return trampolineObj_; } private: friend class DerivedTwo; DerivedTwo * trampolineObj_; void functionOne(); }; using namespace std; int main() { BaseClass * pBaseClass = 0; ConcreteClassOne * pConClassOne = new ConcreteClassOne(); ConcreteClassTwo * pConClassTwo = new ConcreteClassTwo(); pBaseClass = pConClassOne->trampoline(); pBaseClass->functionOne(); pBaseClass = pConClassTwo->trampoline(); pBaseClass->functionOne(); return 0; } void DerivedOne::functionOne() { me_->functionOne(); } void DerivedTwo::functionOne() { me_->functionOne(); } void ConcreteClassOne::functionOne() { cout << "This is ConcreteClassOne" << endl; } void ConcreteClassTwo::functionOne() { cout << "This is ConcreteClassTwo" << endl; }
Advertisements