3 #include "FastDelegate.h"
\r
4 // Demonstrate the syntax for FastDelegates.
\r
5 // -Don Clugston, May 2004.
\r
6 // It's a really boring example, but it shows the most important cases.
\r
8 // Declare some functions of varying complexity...
\r
9 void SimpleStaticFunction(int num, char *str) {
\r
10 printf("In SimpleStaticFunction. Num=%d, str = %s\n", num, str);
\r
13 void SimpleVoidFunction() {
\r
14 printf("In SimpleVoidFunction with no parameters.\n");
\r
21 CBaseClass(char *name) : m_name(name) {};
\r
22 void SimpleMemberFunction(int num, char *str) {
\r
23 printf("In SimpleMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); }
\r
24 int SimpleMemberFunctionReturnsInt(int num, char *str) {
\r
25 printf("In SimpleMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); return -1; }
\r
26 void ConstMemberFunction(int num, char *str) const {
\r
27 printf("In ConstMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str); }
\r
28 virtual void SimpleVirtualFunction(int num, char *str) {
\r
29 printf("In SimpleVirtualFunction in %s. Num=%d, str = %s\n", m_name, num, str); }
\r
30 static void StaticMemberFunction(int num, char *str) {
\r
31 printf("In StaticMemberFunction. Num=%d, str =%s\n", num, str); }
\r
35 double rubbish; // to ensure this class has non-zero size.
\r
37 virtual void UnusedVirtualFunction(void) { }
\r
38 virtual void TrickyVirtualFunction(int num, char *str)=0;
\r
41 class VeryBigClass {
\r
42 int letsMakeThingsComplicated[400];
\r
45 // This declaration ensures that we get a convoluted class heirarchy.
\r
46 class CDerivedClass : public VeryBigClass, virtual public COtherClass, virtual public CBaseClass
\r
48 double m_somemember[8];
\r
50 CDerivedClass() : CBaseClass("Base of Derived") { m_somemember[0]=1.2345; }
\r
51 void SimpleDerivedFunction(int num, char *str) { printf("In SimpleDerived. num=%d\n", num); }
\r
52 virtual void AnotherUnusedVirtualFunction(int num, char *str) {}
\r
53 virtual void TrickyVirtualFunction(int num, char *str) {
\r
54 printf("In Derived TrickyMemberFunction. Num=%d, str = %s\n", num, str);
\r
58 using namespace fastdelegate;
\r
62 // Delegates with up to 8 parameters are supported.
\r
63 // Here's the case for a void function.
\r
64 // We declare a delegate and attach it to SimpleVoidFunction()
\r
65 printf("-- FastDelegate demo --\nA no-parameter delegate is declared using FastDelegate0\n\n");
\r
67 FastDelegate0<> noparameterdelegate(&SimpleVoidFunction);
\r
69 noparameterdelegate(); // invoke the delegate - this calls SimpleVoidFunction()
\r
71 printf("\n-- Examples using two-parameter delegates (int, char *) --\n\n");
\r
73 // By default, the return value is void.
\r
74 typedef FastDelegate2<int, char *> MyDelegate;
\r
76 // If you want to have a non-void return value, put it at the end.
\r
77 typedef FastDelegate2<int, char *, int> IntMyDelegate;
\r
80 MyDelegate funclist[12]; // delegates are initialized to empty
\r
81 CBaseClass a("Base A");
\r
82 CBaseClass b("Base B");
\r
86 IntMyDelegate newdeleg;
\r
87 newdeleg = MakeDelegate(&a, &CBaseClass::SimpleMemberFunctionReturnsInt);
\r
89 // Binding a simple member function
\r
90 funclist[0].bind(&a, &CBaseClass::SimpleMemberFunction);
\r
92 // You can also bind static (free) functions
\r
93 funclist[1].bind(&SimpleStaticFunction);
\r
94 // and static member functions
\r
95 funclist[2].bind(&CBaseClass::StaticMemberFunction);
\r
96 // and const member functions (these only need a const class pointer).
\r
97 funclist[11].bind( (const CBaseClass *)&a, &CBaseClass::ConstMemberFunction);
\r
98 funclist[3].bind( &a, &CBaseClass::ConstMemberFunction);
\r
99 // and virtual member functions
\r
100 funclist[4].bind(&b, &CBaseClass::SimpleVirtualFunction);
\r
102 // You can also use the = operator. For static functions, a fastdelegate
\r
103 // looks identical to a simple function pointer.
\r
104 funclist[5] = &CBaseClass::StaticMemberFunction;
\r
106 // The weird rule about the class of derived member function pointers is avoided.
\r
107 // For MSVC, you can use &CDerivedClass::SimpleVirtualFunction here, but DMC will complain.
\r
108 // Note that as well as .bind(), you can also use the MakeDelegate()
\r
109 // global function.
\r
110 funclist[6] = MakeDelegate(&d, &CBaseClass::SimpleVirtualFunction);
\r
112 // The worst case is an abstract virtual function of a virtually-derived class
\r
113 // with at least one non-virtual base class. This is a VERY obscure situation,
\r
114 // which you're unlikely to encounter in the real world.
\r
115 // FastDelegate versions prior to 1.3 had problems with this case on VC6.
\r
116 // Now, it works without problems on all compilers.
\r
117 funclist[7].bind(&c, &CDerivedClass::TrickyVirtualFunction);
\r
118 // BUT... in such cases you should be using the base class as an
\r
119 // interface, anyway.
\r
120 funclist[8].bind(&c, &COtherClass::TrickyVirtualFunction);
\r
121 // Calling a function that was first declared in the derived class is straightforward
\r
122 funclist[9] = MakeDelegate(&c, &CDerivedClass::SimpleDerivedFunction);
\r
124 // You can also bind directly using the constructor
\r
125 MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction);
\r
127 char *msg = "Looking for equal delegate";
\r
128 for (int i=0; i<12; i++) {
\r
130 // The == and != operators are provided
\r
131 // Note that they work even for inline functions.
\r
132 if (funclist[i]==dg) { msg = "Found equal delegate"; };
\r
133 // operator ! can be used to test for an empty delegate
\r
134 // You can also use the .empty() member function.
\r
135 if (!funclist[i]) {
\r
136 printf("Delegate is empty\n");
\r
138 // Invocation generates optimal assembly code.
\r
139 funclist[i](i, msg);
\r