<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Callback</title>
</head>

<body>



<p align="left"><span lang="en-ca"><font size="6" color="#FF0000"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
 
</b></font></span><font size="6" color="#FF0000"><b>Comparison of Callback and 
Template</b></font></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A. First Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is only a simple demo of comparison of &quot;callback&quot; and template implementation.</b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<p ALIGN="LEFT"><font size="2"><b>Suppose you need write a general method for 
other users, allowing the user to use its self-defined method in </b></font></p>
<p ALIGN="LEFT"><font size="2"><b>your method, how to implement it? </b></font>
</p>
<p ALIGN="LEFT"><font size="2"><b>The typical answer is &quot;callback&quot; function. 
Besides it, you can use a template class. Here I just want to demo</b></font></p>
<p ALIGN="LEFT"><font size="2"><b>how to do it.</b></font></p>
<pre>这个小例子是我们都玩过的剪刀石头布。有一个裁判程序（judge)，你和我都有一个出手的程序(youFight, meFight)和以及各自的策略数据(yourStrategy,</pre>
<pre>myStrategy)。使用的时候就把他们都当作参数带入裁判程序。</pre>
<pre>为什么要这样写呢？原因就是flexibility，假如，你忽然想要改变策略数据的话，就换一个参数带入就好了，裁判时不用变得。你也可以改变你的出牌的方法</pre>
<pre>也就是重新定义一个新函数，只要参数类型个数，返回值类型与现在的一样就可以了，比如说，改变shift的值，或者就干脆用随机数等等。</pre>
<div align="left">
  <p ALIGN="LEFT">　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca"><a name="explain"></a>C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <font size="2">
  <span lang="en-ca"><b>T</b></span><b>he program is like a little game which we 
  all played in childhood: &quot;scissors-stone-cloth&quot;. The game is cycle-</b></font></div>
<div align="left">
  　</div>
<div align="left">
  <font size="2"><b>win: scissors&gt;cloth&gt;stone<span lang="en-ca">&gt;scissors.
  </span> </b></font></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>Now you are asked to write a &quot;judge&quot; 
  program which take two player's parameters. The parameter includes their</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>strategy of how to play the game, or more 
  probably along with their data of strategy, say an array of playing</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>strategy. Your &quot;judge&quot; program call the 
  parameters and get the choices from each of two players and judge the </b>
  </font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>the winner, show the winning information. 
  That's it.</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>The first approach is by &quot;callback&quot; 
  function which passes function pointer as parameter, along with their </b>
  </font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>strategy array. It is most common one.</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>The second approach is to pass a 
  user-defined class which has &quot;static&quot; method and data. When the static method
  </b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>is called, they will extract static 
  strategy from its private data member and give the choice. It is more</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>completely wrapped method. However, there 
  is a big bug of VC++6.0 as the compiler doesn't recognize the template</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>function from its declaration. This is a 
  same annoying bug I encountered when overloading friend function of </b>
  </font></span></div>
<div align="left">
  　</div>
<div align="left">
  <span lang="en-ca"><font size="2"><b>&quot;ostream&quot;.</b></font></span></div>
<div align="left">
  　</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">E</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre>　</pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">F</span>.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>File listing</b></font></span></pre>
</div>
<div align="left">
  <pre><font size="3"><b>1<span lang="en-ca">. </span></b></font><span lang="en-ca"><font size="3"><b>callback.cpp</b></font></span></pre>
  <pre><span lang="en-ca"><font size="3"><b>2</b></font></span><font size="3"><b><span lang="en-ca">. </span></b></font><span lang="en-ca"><font size="3"><b>template.cpp</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="5" color="#FF0000"><b>CallBack Method:</b></font></span></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: callback.cpp</b></font></span></pre>
</div>
<pre>#include &lt;iostream&gt;

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]={&quot;Scissor&quot;, &quot;Stone&quot;, &quot;Cloth&quot;};

//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&lt;MatchNumber; i++)
	{
		you=youPlay(yourParam, i);
		me=myPlay(myParam, i);
		cout&lt;&lt;&quot;your type is:&quot;&lt;&lt;typeStr[you]&lt;&lt;endl;
		cout&lt;&lt;&quot;my type is:&quot;&lt;&lt;typeStr[me]&lt;&lt;endl;
		switch (you-me)
		{
			
		case 0:
			
			cout&lt;&lt;&quot;it is a tie on match no.&quot;&lt;&lt;i+1&lt;&lt;endl;
			break;
		case 1:
		case -2:
			cout&lt;&lt;&quot;you win on match no. &quot;&lt;&lt;i+1&lt;&lt;endl;
			break;
		case -1:
		case 2:
			cout&lt;&lt;&quot;you lose on match no.&quot;&lt;&lt;i+1&lt;&lt;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];
}</pre>
<pre><span lang="en-ca"><font size="5" color="#FF0000"><b>Template Method:</b></font></span></pre>
<pre><b><font color="#0000FF"><span lang="en-ca">The result of callback method:</span></font></b></pre>
<pre><span lang="en-ca">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</span></pre>
<pre>
</pre>

<pre><span lang="en-ca"><font size="3" color="#FF0000"><b>file name: rules.cpp </b></font></span></pre>

<pre>#include &lt;iostream&gt;

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]={&quot;Scissor&quot;, &quot;Stone&quot;, &quot;Cloth&quot;};


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&lt;class yourPlayClass , class myPlayClass&gt;
void judge();
*/
//and put the implementation below after &quot;MAIN&quot; function
//then you will get memory access error, because 
//what you declared is not implemented!!!!!
template&lt;class yourPlayClass , class myPlayClass&gt;
void judge()
{
	int you, me;
	for (int i=0; i&lt;MatchNumber; i++)
	{
		you=yourPlayClass::youFight(i);
		me=myPlayClass::meFight(i);
		cout&lt;&lt;&quot;your type is:&quot;&lt;&lt;typeStr[you]&lt;&lt;endl;
		cout&lt;&lt;&quot;my type is:&quot;&lt;&lt;typeStr[me]&lt;&lt;endl;
		switch (you-me)
		{
			
		case 0:
			
			cout&lt;&lt;&quot;it is a tie on match no.&quot;&lt;&lt;i+1&lt;&lt;endl;
			break;
		case 1:
		case -2:
			cout&lt;&lt;&quot;you win on match no. &quot;&lt;&lt;i+1&lt;&lt;endl;
			break;
		case -1:
		case 2:
			cout&lt;&lt;&quot;you lose on match no.&quot;&lt;&lt;i+1&lt;&lt;endl;
			break;
		}
	}
}



int main()
{
	judge&lt;YourPlay, MyPlay&gt;();
	return 0;
}



<b><font color="#0000FF"><span lang="en-ca">The result of callback method:</span></font></b></pre>
<pre><font face="Times New Roman"><span lang="en-ca">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</span>


</font>

</pre>
<pre>　</pre>

<pre></pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="game24.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm">
<img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>