A delegate is a helper object used by another object. The delegator may send the delegate certain messages, and provide a default implementation when there is no delegate or the delegate does not respond to a message. This pattern is heavily used in Cocoa framework on Mac OS X. See also wp:Delegation pattern.
Objects responsibilities:
Delegator:
- Keep an optional delegate instance.
- Implement “operation” method, returning the delegate “thing” if the delegate respond to “thing”, or the string “default implementation”.
Delegate:
- Implement “thing” and return the string “delegate implementation”
Show how objects are created and used. First, without a delegate, then with a delegate that does not implement “thing”, and last with a delegate that implements “thing”.
Delegates in the C# or D style are available in C++ through std::tr1::function class template. These delegates don’t exactly match this problem statement though, as they only support a single method call (which is operator()), and so don’t support querying for support of particular methods.
#include <tr1/memory> #include <string> #include <iostream> #include <tr1/functional> using namespace std; using namespace std::tr1; using std::tr1::function; // interface for all delegates class IDelegate { public: virtual ~IDelegate() {} }; //interface for delegates supporting thing class IThing { public: virtual ~IThing() {} virtual std::string Thing() = 0; }; // Does not handle Thing class DelegateA : virtual public IDelegate { }; // Handles Thing class DelegateB : public IThing, public IDelegate { std::string Thing() { return "delegate implementation"; } }; class Delegator { public: std::string Operation() { if(Delegate) //have delegate if (IThing * pThing = dynamic_cast<IThing*>(Delegate.get())) //delegate provides IThing interface return pThing->Thing(); return "default implementation"; } shared_ptr<IDelegate> Delegate; }; int main() { shared_ptr<DelegateA> delegateA(new DelegateA()); shared_ptr<DelegateB> delegateB(new DelegateB()); Delegator delegator; // No delegate std::cout << delegator.Operation() << std::endl; // Delegate doesn't handle "Thing" delegator.Delegate = delegateA; std::cout << delegator.Operation() << std::endl; // Delegate handles "Thing" delegator.Delegate = delegateB; std::cout << delegator.Operation() << std::endl; /* Prints: default implementation default implementation delegate implementation */ }
Content is available under GNU Free Documentation License 1.2.