| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- // Member Function Pointers and the Fastest Possible C++ Delegates.cpp : This file contains the 'main' function. Program execution begins and ends there.
- // https://www.codeproject.com/KB/cpp/FastDelegate.aspx
- /*
-
- */
- #include <iostream>
- #include <stdio.h>
- #include "FastDelegate.h"
- // Demonstrate the syntax for FastDelegates.
- // -Don Clugston, May 2004.
- // It's a really boring example, but it shows the most important cases.
- // Declare some functions of varying complexity...
- void SimpleStaticFunction(int num, char* str) {
- printf("In SimpleStaticFunction. Num=%d, str = %s\n", num, str);
- }
- void SimpleVoidFunction() {
- printf("In SimpleVoidFunction with no parameters.\n");
- }
- class CBaseClass {
- protected:
- char* m_name;
- public:
- CBaseClass(char* name) : m_name(name) {};
- void SimpleMemberFunction(int num, char* str) {
- printf("In SimpleMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str);
- }
- int SimpleMemberFunctionReturnsInt(int num, char* str) {
- printf("In SimpleMemberFunction in %s. Num=%d, str = %s Return: -1\n", m_name, num, str); return -2;
- }
- void ConstMemberFunction(int num, char* str) const {
- printf("In ConstMemberFunction in %s. Num=%d, str = %s\n", m_name, num, str);
- }
- virtual void SimpleVirtualFunction(int num, char* str) {
- printf("In SimpleVirtualFunction in %s. Num=%d, str = %s\n", m_name, num, str);
- }
- static void StaticMemberFunction(int num, char* str) {
- printf("In StaticMemberFunction. Num=%d, str =%s\n", num, str);
- }
- };
- class COtherClass {
- double rubbish = 12; // to ensure this class has non-zero size.
- public:
- virtual void UnusedVirtualFunction(void) {}
- virtual void TrickyVirtualFunction(int num, char* str) = 0;
- };
- class VeryBigClass {
- int letsMakeThingsComplicated[400];
- };
- // This declaration ensures that we get a convoluted class heirarchy.
- class CDerivedClass : public VeryBigClass, virtual public COtherClass, virtual public CBaseClass
- {
- double m_somemember[8];
- public:
- CDerivedClass() : CBaseClass((char*)"Base of Derived") { m_somemember[0] = 1.2345; }
- void SimpleDerivedFunction(int num, char* str) { printf("In SimpleDerived. num=%d\n", num); }
- virtual void AnotherUnusedVirtualFunction(int num, char* str) {}
- virtual void TrickyVirtualFunction(int num, char* str) {
- printf("In Derived TrickyMemberFunction. Num=%d, str = %s\n", num, str);
- }
- };
- using namespace fastdelegate;
- int main(void)
- {
- // Delegates with up to 8 parameters are supported.
- // Here's the case for a void function.
- // We declare a delegate and attach it to SimpleVoidFunction()
- printf("-- FastDelegate demo --\nA no-parameter delegate is declared using FastDelegate0\n\n");
- FastDelegate0<> noparameterdelegate(&SimpleVoidFunction);
- noparameterdelegate(); // invoke the delegate - this calls SimpleVoidFunction()
- printf("\n-- Examples using two-parameter delegates (int, char *) --\n\n");
- // By default, the return value is void.
- typedef FastDelegate2<int, char*> MyDelegate;
- // If you want to have a non-void return value, put it at the end.
- typedef FastDelegate2<int, char*, int> IntMyDelegate;
- MyDelegate funclist[12]; // delegates are initialized to empty
- CBaseClass a((char*)"Base A");
- CBaseClass b((char*)"Base B");
- CDerivedClass d;
- CDerivedClass c;
- IntMyDelegate newdeleg;
- newdeleg = MakeDelegate(&a, &CBaseClass::SimpleMemberFunctionReturnsInt);
- printf("Return value: %d\n", newdeleg(0, (char*)"return value"));
- // Binding a simple member function
- funclist[0].bind(&a, &CBaseClass::SimpleMemberFunction);
- // You can also bind static (free) functions
- funclist[1].bind(&SimpleStaticFunction);
- // and static member functions
- funclist[2].bind(&CBaseClass::StaticMemberFunction);
- // and const member functions (these only need a const class pointer).
- funclist[11].bind((const CBaseClass*)&a, &CBaseClass::ConstMemberFunction);
- funclist[3].bind(&a, &CBaseClass::ConstMemberFunction);
- // and virtual member functions
- funclist[4].bind(&b, &CBaseClass::SimpleVirtualFunction);
- // You can also use the = operator. For static functions, a fastdelegate
- // looks identical to a simple function pointer.
- funclist[5] = &CBaseClass::StaticMemberFunction;
- // The weird rule about the class of derived member function pointers is avoided.
- // For MSVC, you can use &CDerivedClass::SimpleVirtualFunction here, but DMC will complain.
- // Note that as well as .bind(), you can also use the MakeDelegate()
- // global function.
- funclist[6] = MakeDelegate(&d, &CBaseClass::SimpleVirtualFunction);
- // The worst case is an abstract virtual function of a virtually-derived class
- // with at least one non-virtual base class. This is a VERY obscure situation,
- // which you're unlikely to encounter in the real world.
- // FastDelegate versions prior to 1.3 had problems with this case on VC6.
- // Now, it works without problems on all compilers.
- funclist[7].bind(&c, &CDerivedClass::TrickyVirtualFunction);
- // BUT... in such cases you should be using the base class as an
- // interface, anyway.
- funclist[8].bind(&c, &COtherClass::TrickyVirtualFunction);
- // Calling a function that was first declared in the derived class is straightforward
- funclist[9] = MakeDelegate(&c, &CDerivedClass::SimpleDerivedFunction);
- // You can also bind directly using the constructor
- MyDelegate dg(&b, &CBaseClass::SimpleVirtualFunction);
- char* msg = (char*)"Looking for equal delegate";
- for (int i = 0; i < 12; i++) {
- printf("%d :", i);
- // The == and != operators are provided
- // Note that they work even for inline functions.
- if (funclist[i] == dg) { msg = (char*)"Found equal delegate"; };
- // operator ! can be used to test for an empty delegate
- // You can also use the .empty() member function.
- if (!funclist[i]) {
- printf("Delegate is empty\n");
- }
- else {
- // Invocation generates optimal assembly code.
- funclist[i](i, msg);
- };
- }
- return 0;
- }
- /*
- -- FastDelegate demo --
- A no-parameter delegate is declared using FastDelegate0
- In SimpleVoidFunction with no parameters.
- -- Examples using two-parameter delegates (int, char *) --
- In SimpleMemberFunction in Base A. Num=0, str = return value Return: -1
- Return value: -2
- 0 :In SimpleMemberFunction in Base A. Num=0, str = Looking for equal delegate
- 1 :In SimpleStaticFunction. Num=1, str = Looking for equal delegate
- 2 :In StaticMemberFunction. Num=2, str =Looking for equal delegate
- 3 :In ConstMemberFunction in Base A. Num=3, str = Looking for equal delegate
- 4 :In SimpleVirtualFunction in Base B. Num=4, str = Found equal delegate
- 5 :In StaticMemberFunction. Num=5, str =Found equal delegate
- 6 :In SimpleVirtualFunction in Base of Derived. Num=6, str = Found equal delegate
- 7 :In Derived TrickyMemberFunction. Num=7, str = Found equal delegate
- 8 :In Derived TrickyMemberFunction. Num=8, str = Found equal delegate
- 9 :In SimpleDerived. num=9
- 10 :Delegate is empty
- 11 :In ConstMemberFunction in Base A. Num=11, str = Found equal delegate
- */
|