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