Comparison of Callback and Template
A. First Edition
This is only a simple demo of comparison of "callback" and template implementation.
Suppose you need write a general method for other users, allowing the user to use its self-defined method in
your method, how to implement it?
The typical answer is "callback" function. Besides it, you can use a template class. Here I just want to demo
how to do it.
这个小例子是我们都玩过的剪刀石头布。有一个裁判程序(judge),你和我都有一个出手的程序(youFight, meFight)和以及各自的策略数据(yourStrategy,
myStrategy)。使用的时候就把他们都当作参数带入裁判程序。
为什么要这样写呢?原因就是flexibility,假如,你忽然想要改变策略数据的话,就换一个参数带入就好了,裁判时不用变得。你也可以改变你的出牌的方法
也就是重新定义一个新函数,只要参数类型个数,返回值类型与现在的一样就可以了,比如说,改变shift的值,或者就干脆用随机数等等。
E.Further improvement
F.File listing
1. callback.cpp
2. template.cpp
CallBack Method:
file name: callback.cpp
#include <iostream> using namespace std; //this is not a program, but a joke...hahha... const int MatchNumber=10; //you know what they are, right? //we all play this little game enum FightType {Scissor, Stone, Cloth}; char* typeStr[3]={"Scissor", "Stone", "Cloth"}; //this is the sequence you might play int yourStrategy[MatchNumber]={2,1,0,2,1,2,0,2,1,1}; //this is the sequence I might play int myStrategy[MatchNumber]={0,1,2,1,2,1,0,2,1,0}; //this is the match judge, with two your play function and your strategy //and my function and my strategy void judge(int (* youPlay)(int* yourParam, int theNumber), int* yourParam, int (*myPlay)(int* myParam, int theNumber), int* myParam); //actually this is the function you defined here int youFight(int* youParam, int index); //I won't repeat int meFight(int* myParam, int index); int main() { judge(youFight, yourStrategy, meFight, myStrategy); return 0; } void judge(int (* youPlay)(int* theParam, int index), int* yourParam, int (*myPlay)(int* theParam, int index), int* myParam) { int you, me; for (int i=0; i<MatchNumber; i++) { you=youPlay(yourParam, i); me=myPlay(myParam, i); cout<<"your type is:"<<typeStr[you]<<endl; cout<<"my type is:"<<typeStr[me]<<endl; switch (you-me) { case 0: cout<<"it is a tie on match no."<<i+1<<endl; break; case 1: case -2: cout<<"you win on match no. "<<i+1<<endl; break; case -1: case 2: cout<<"you lose on match no."<<i+1<<endl; break; } } } //you can change your strategy simple by.... int youFight(int* youParam, int index) { //actually you can define any method you imagine return yourStrategy[(index+5)%MatchNumber]; } int meFight(int* myParam, int index) { //by shifting the current strategy, you have a new one return myStrategy[(index+2)%MatchNumber]; }
Template Method:
The result of callback method:
your type is:Cloth
my type is:Cloth
it is a tie on match no.1
your type is:Scissor
my type is:Stone
you lose on match no.2
your type is:Cloth
my type is:Cloth
it is a tie on match no.3
your type is:Stone
my type is:Stone
it is a tie on match no.4
your type is:Stone
my type is:Scissor
you win on match no. 5
your type is:Cloth
my type is:Cloth
it is a tie on match no.6
your type is:Stone
my type is:Stone
it is a tie on match no.7
your type is:Scissor
my type is:Scissor
it is a tie on match no.8
your type is:Cloth
my type is:Scissor
you lose on match no.9
your type is:Stone
my type is:Stone
it is a tie on match no.10
Press any key to continue
file name: rules.cpp
#include <iostream>
using namespace std;
//this is not a program, but a joke...hahha...
const int MatchNumber=10;
//you know what they are, right?
//we all play this little game
enum FightType
{Scissor, Stone, Cloth};
char* typeStr[3]={"Scissor", "Stone", "Cloth"};
class YourPlay
{
private:
static int yourStrategy[MatchNumber];
public:
static int youFight(int index)
{
//actually you can define any method you imagine
return yourStrategy[(index+5)%MatchNumber];
}
};
class MyPlay
{
private:
static int myStrategy[MatchNumber];
public:
static int meFight(int index)
{
//by shifting the current strategy, you have a new one
return myStrategy[(index+2)%MatchNumber];
}
};
//the static strategy is initialized here
int YourPlay::yourStrategy[MatchNumber]={2,1,0,2,1,2,0,2,1,1};
int MyPlay::myStrategy[MatchNumber]={0,1,2,1,2,1,0,2,1,0};
//THIS IS THE BUG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//you cannot declare the template function
//compiler don't recognize it!!!
//believe it or not, try declare it as following:
/*
template<class yourPlayClass , class myPlayClass>
void judge();
*/
//and put the implementation below after "MAIN" function
//then you will get memory access error, because
//what you declared is not implemented!!!!!
template<class yourPlayClass , class myPlayClass>
void judge()
{
int you, me;
for (int i=0; i<MatchNumber; i++)
{
you=yourPlayClass::youFight(i);
me=myPlayClass::meFight(i);
cout<<"your type is:"<<typeStr[you]<<endl;
cout<<"my type is:"<<typeStr[me]<<endl;
switch (you-me)
{
case 0:
cout<<"it is a tie on match no."<<i+1<<endl;
break;
case 1:
case -2:
cout<<"you win on match no. "<<i+1<<endl;
break;
case -1:
case 2:
cout<<"you lose on match no."<<i+1<<endl;
break;
}
}
}
int main()
{
judge<YourPlay, MyPlay>();
return 0;
}
The result of callback method:
your type is:Cloth
my type is:Cloth
it is a tie on match no.1
your type is:Scissor
my type is:Stone
you lose on match no.2
your type is:Cloth
my type is:Cloth
it is a tie on match no.3
your type is:Stone
my type is:Stone
it is a tie on match no.4
your type is:Stone
my type is:Scissor
you win on match no. 5
your type is:Cloth
my type is:Cloth
it is a tie on match no.6
your type is:Stone
my type is:Stone
it is a tie on match no.7
your type is:Scissor
my type is:Scissor
it is a tie on match no.8
your type is:Cloth
my type is:Scissor
you lose on match no.9
your type is:Stone
my type is:Stone
it is a tie on match no.10
Press any key to continue