﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-#ant-随笔分类-C++</title><link>http://www.cppblog.com/ant/category/4993.html</link><description>The dreams in which I'm dying are the best I've ever had...</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 20:38:15 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 20:38:15 GMT</pubDate><ttl>60</ttl><item><title>Win32 Service的简单封装</title><link>http://www.cppblog.com/ant/archive/2007/09/24/32769.html</link><dc:creator>蚂蚁终结者</dc:creator><author>蚂蚁终结者</author><pubDate>Mon, 24 Sep 2007 05:01:00 GMT</pubDate><guid>http://www.cppblog.com/ant/archive/2007/09/24/32769.html</guid><wfw:comment>http://www.cppblog.com/ant/comments/32769.html</wfw:comment><comments>http://www.cppblog.com/ant/archive/2007/09/24/32769.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/ant/comments/commentRss/32769.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ant/services/trackbacks/32769.html</trackback:ping><description><![CDATA[<p>前段时间学习Windows程序设计，刚好学到Win32 Service，于是写了两个简单的类：BaseService和ServiceCtrl。虽然功能比较简单，但是也能适用于大多数情况。下面介绍一下简单用法，如果你刚好需要写一些简单的服务程序，这两个类也许能派上用场：<br><br><span style="FONT-SIZE: 14pt"><strong style="COLOR: #993366">1. BaseService<br></strong></span><em style="COLOR: #333399">BaseService.h<br></em></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">#ifndef&nbsp;BASE_SERVICE_H<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">#define&nbsp;BASE_SERVICE_H<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;BaseService&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span></font> <font face="Courier New"><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;explicit&nbsp;BaseService(LPCTSTR&nbsp;szServiceName,<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwServiceType&nbsp;</span><span style="COLOR: #000000">=</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;SERVICE_WIN32_OWN_PROCESS,<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwStartType&nbsp;</span><span style="COLOR: #000000">=</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;SERVICE_AUTO_START);<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #000000">~</span></font> <font face="Courier New"><span style="COLOR: #000000">BaseService()&nbsp;{}<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;ParseStandardArgs(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;argv[]);<br></span><span style="COLOR: #008080">11</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;IsInstalled();<br></span><span style="COLOR: #008080">12</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Install();<br></span><span style="COLOR: #008080">13</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Uninstall();<br></span><span style="COLOR: #008080">14</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Start();<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">private</span></font> <font face="Courier New"><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Run()&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span></font> <font face="Courier New"><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;bool&nbsp;OnInitialize()&nbsp;{&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span></font> <font face="Courier New"><span style="COLOR: #000000">;&nbsp;}<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;OnStop()&nbsp;{}<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;OnPause()&nbsp;{}<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;OnContinue()&nbsp;{}<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;OnInterrogate()&nbsp;{}<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;OnShutdown()&nbsp;{}<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;OnUserControl(DWORD&nbsp;dwControl)&nbsp;{}<br></span><span style="COLOR: #008080">24</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;...<br></span><span style="COLOR: #008080">25</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">26</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">#endif</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">BASE_SERVICE_H</span><span style="COLOR: #008000">*/</span></font> </div>
<p>要实现自己的服务类只需从BaseService继承并且Override相关的virtual函数即可，下面示范一个BeepService类，该服务只是简单地每隔2秒beep一下，为了简单所有代码均放在.h文件中：<br><em style="COLOR: #333399">BeepService.h</em></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">#ifndef&nbsp;BEEP_SERVICE_H<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">#define&nbsp;BEEP_SERVICE_H<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">BaseService.h</span><span style="COLOR: #000000">"</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;5</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;BeepService&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;BaseService&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span></font> <font face="Courier New"><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BeepService(LPCTSTR&nbsp;szServiceName)<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:BaseService(szServiceName)<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,m_bPaused(</span><span style="COLOR: #0000ff">false</span></font> <font face="Courier New"><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,m_bRunning(</span><span style="COLOR: #0000ff">false</span></font> <font face="Courier New"><span style="COLOR: #000000">)&nbsp;{}<br></span><span style="COLOR: #008080">12</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;OnStop()&nbsp;{&nbsp;m_bRunning&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">false</span></font> <font face="Courier New"><span style="COLOR: #000000">;&nbsp;}<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;OnPause()&nbsp;{&nbsp;m_bPaused&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span></font> <font face="Courier New"><span style="COLOR: #000000">;&nbsp;}<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;OnContinue()&nbsp;{&nbsp;m_bPaused&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">false</span></font> <font face="Courier New"><span style="COLOR: #000000">;&nbsp;}<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;</span><span style="COLOR: #0000ff">void</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;Run()&nbsp;{<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_bRunning&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">true</span></font> <font face="Courier New"><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;(m_bRunning)&nbsp;{<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span></font> <font face="Courier New"><span style="COLOR: #000000">m_bPaused)<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Beep(</span><span style="COLOR: #000000">800</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">800</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">2000</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">22</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">23</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">private</span></font> <font face="Courier New"><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">volatile</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;bool&nbsp;m_bPaused;<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">volatile</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;bool&nbsp;m_bRunning;<br></span><span style="COLOR: #008080">27</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">28</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">#endif</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">BEEP_SERVICE_H</span><span style="COLOR: #008000">*/</span></font> </div>
<p>通常来说只须要Override上面的4个virtual函数就OK了：<br>在<em>Run()</em>中进行实际的工作，<em>OnStop(),OnPause(),OnContinue()</em>则是为了响应Service Control Manager的控制。<br><em style="COLOR: #333399"><br>test.cpp<br></em></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">&gt;</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">tchar.h</span><span style="COLOR: #000000">&gt;</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">BeepService.h</span><span style="COLOR: #000000">"</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;5</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span></font> <font face="Courier New"><span style="COLOR: #000000">argv[])&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;BeepService&nbsp;beepService(_T(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">BeepService</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">));<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span></font> <font face="Courier New"><span style="COLOR: #000000">beepService.ParseStandardArgs(argc,&nbsp;argv))&nbsp;{<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;(beepService.IsInstalled())&nbsp;{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span></font> <font face="Courier New"><span style="COLOR: #000000">beepService.Start())<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">The&nbsp;service&nbsp;can&nbsp;not&nbsp;run&nbsp;from&nbsp;command&nbsp;line.\n</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="COLOR: #0000ff">else</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;{<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">The&nbsp;service&nbsp;is&nbsp;not&nbsp;installed,&nbsp;</span><span style="COLOR: #000000">"</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">use&nbsp;\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">s&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">i\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&nbsp;to&nbsp;install.\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;argv[</span><span style="COLOR: #000000">0</span></font> <font face="Courier New"><span style="COLOR: #000000">]);<br></span><span style="COLOR: #008080">16</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">17</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span></font> <font face="Courier New"><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">}</span></font> </div>
<p>假设编译后生成的exe文件为beep.exe，则在命令行中可以如下使用：<br><em style="COLOR: #333399">(1). beep -i&nbsp;&nbsp;&nbsp; 安装service(安装以后系统运行时会自动启动)<br>(2). beep -u&nbsp;&nbsp;&nbsp;卸载service(如果service正在运行，则先停止service再卸载)<br></em>BaseServiced&nbsp;的ParseStandardArgs正是用来解析上述两个命令。<br><br><span style="FONT-SIZE: 14pt"><strong style="COLOR: #993366">2. ServiceCtrl<br></strong></span>虽然Windows自带的Service Control Manager可以控制服务程序，但是很多时候我们都需要用代码控制，这就用到ServiceCtrl类，该类的接口如下：<br><em style="COLOR: #333399">ServiceCtrl.h</em></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">#ifndef&nbsp;SERVICE_CTRL_H<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">#define&nbsp;SERVICE_CTRL_H<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;ServiceCtrl&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span></font> <font face="Courier New"><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ServiceCtrl(LPCTSTR&nbsp;szServiceName);<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span></font> <font face="Courier New"><span style="COLOR: #000000">ServiceCtrl();<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Start();<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Pause();<br></span><span style="COLOR: #008080">10</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Continue();<br></span><span style="COLOR: #008080">11</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Stop();<br></span><span style="COLOR: #008080">12</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;Interrogate();<br></span><span style="COLOR: #008080">13</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;bool&nbsp;UserControl(DWORD&nbsp;dwControl);<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;State()&nbsp;</span><span style="COLOR: #0000ff">const</span></font> <font face="Courier New"><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">15</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;...<br></span><span style="COLOR: #008080">16</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">17</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">#endif</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">SERVICE_CTRL_H</span><span style="COLOR: #008000">*/</span></font> </div>
<p>接口比较直观没什么好说的，看下面的示例代码：<br><em><font color=#333399>test.cpp</font></em></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">&gt;</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">tchar.h</span><span style="COLOR: #000000">&gt;</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">exception</span><span style="COLOR: #000000">&gt;</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">BeepService.h</span><span style="COLOR: #000000">"</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">ServiceCtrl.h</span><span style="COLOR: #000000">"</span></font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;7</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span></font> <font face="Courier New"><span style="COLOR: #000000">argv[])&nbsp;{<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;</font> <span style="COLOR: #000000"><br></span><font face="Courier New"><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServiceCtrl&nbsp;servCtrl(_T(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">BeepService</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">));<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(servCtrl.State()&nbsp;</span><span style="COLOR: #000000">!=</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;SERVICE_STOPPED)&nbsp;{<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Service&nbsp;already&nbsp;started.\n</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="COLOR: #0000ff">else</span></font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;{<br></span><span style="COLOR: #008080">15</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;servCtrl.Start();<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Start.\n</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">6000</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">18</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;servCtrl.Pause();<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Pause.\n</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">6000</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">21</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;servCtrl.Continue();<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Continue.\n</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sleep(</span><span style="COLOR: #000000">6000</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">24</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;servCtrl.Stop();<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Stop.\n</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">26</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">&nbsp;(std::exception&nbsp;</span><span style="COLOR: #000000">&amp;</span></font> <font face="Courier New"><span style="COLOR: #000000">e)&nbsp;{<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s\n</span><span style="COLOR: #000000">"</span></font> <font face="Courier New"><span style="COLOR: #000000">,&nbsp;e.what());<br></span><span style="COLOR: #008080">29</span>&nbsp;</font> <font face="Courier New"><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span></font> <font face="Courier New"><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000">}</span></font> </div>
<br>源代码：<a title=点击下载 href="http://www.cppblog.com/Files/ant/Service.rar">点击下载</a><br>
<img src ="http://www.cppblog.com/ant/aggbug/32769.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ant/" target="_blank">蚂蚁终结者</a> 2007-09-24 13:01 <a href="http://www.cppblog.com/ant/archive/2007/09/24/32769.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从Win32 API封装Thread类[2]</title><link>http://www.cppblog.com/ant/archive/2007/08/31/31280.html</link><dc:creator>蚂蚁终结者</dc:creator><author>蚂蚁终结者</author><pubDate>Fri, 31 Aug 2007 03:58:00 GMT</pubDate><guid>http://www.cppblog.com/ant/archive/2007/08/31/31280.html</guid><wfw:comment>http://www.cppblog.com/ant/comments/31280.html</wfw:comment><comments>http://www.cppblog.com/ant/archive/2007/08/31/31280.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/ant/comments/commentRss/31280.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ant/services/trackbacks/31280.html</trackback:ping><description><![CDATA[在上一篇中介绍了创建Thread的两种方法：从Thread类继承或者实现Runnable接口。有时候这并不是特别方便，我们需要的是更灵活的方法，比如像boost库中的Thread一样可以用普通函数和函数对象<br />(<em>functor</em> and <em>function object</em>)作为构造函数参数。如果你熟悉STL，你应该熟悉bind1st和bind2nd这两个函数配接器(<em>function adapter</em>)，bind1st和bind2nd可以将一个二元函数(<em>binary function</em>)转换成一元函数(<em>unary function</em>)。为了使Thread类能够用普通函数和函数对象作为参数，我们需要一个bind将一元函数转换成无参函数：<br /><em style="COLOR: #333399">bind.h<br /></em><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080"> 1</span> </font><font face="Courier New"><span style="COLOR: #000000">#ifndef BIND_H<br /></span><span style="COLOR: #008080"> 2</span> </font><font face="Courier New"><span style="COLOR: #000000">#define BIND_H<br /></span><span style="COLOR: #008080"> 3</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> _Result</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 5</span> </font><font face="Courier New"><span style="COLOR: #000000">struct trivial_function {<br /></span><span style="COLOR: #008080"> 6</span> </font><font face="Courier New"><span style="COLOR: #000000">    typedef _Result result_type;<br /></span><span style="COLOR: #008080"> 7</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080"> 8</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> _Operation</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> binder : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> trivial_function</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename _Operation::result_type</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span></font><font face="Courier New"><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    binder(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> _Operation </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">x, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> typename _Operation::argument_type </span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">y)<br /></span><span style="COLOR: #008080">13</span> </font><font face="Courier New"><span style="COLOR: #000000">        :op(x), value(y) {}<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">    typename _Operation::result_type operator()() </span><span style="COLOR: #0000ff">const</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span></font><font face="Courier New"><span style="COLOR: #000000"> op(value);<br /></span><span style="COLOR: #008080">16</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">protected</span></font><font face="Courier New"><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">18</span> </font><font face="Courier New"><span style="COLOR: #000000">    _Operation op;<br /></span><span style="COLOR: #008080">19</span> </font><font face="Courier New"><span style="COLOR: #000000">    typename _Operation::argument_type value;<br /></span><span style="COLOR: #008080">20</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">21</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> _Operation, </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> _Tp</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">23</span> <span style="COLOR: #000000">inline binder</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">_Operation</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000"> <br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000">bind(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> _Operation</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> __fn, </span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> _Tp</span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000"> __x) <br /></span><span style="COLOR: #008080">25</span> </font><font face="Courier New"><span style="COLOR: #000000">{<br /></span><span style="COLOR: #008080">26</span> </font><font face="Courier New"><span style="COLOR: #000000">    typedef typename _Operation::argument_type _Arg_type;<br /></span><span style="COLOR: #008080">27</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> binder</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">_Operation</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000">(__fn, _Arg_type(__x));<br /></span><span style="COLOR: #008080">28</span> </font><font face="Courier New"><span style="COLOR: #000000">}<br /></span><span style="COLOR: #008080">29</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">30</span> <span style="COLOR: #000000">#endif</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">BIND_H</span><span style="COLOR: #008000">*/</span></font></div><br />有了bind我们还需要修改Thread类的构造函数，显然我们必须将构造函数声明为成员模板(还有一种方法也可以达到同样的目的，就是把Thread类声明为模板，但是这样的设计好像不太好)，这样才能够让Thread类的构造函数可以接受各种类型的参数，修改后的构造函数应该能够使用如下三种类型的参数：<br /><em style="COLOR: #993300">1.Runnable *<br />2.no argument function<br />3.no argument functor<br /></em>下面是修改后的头文件：<br /><em style="COLOR: #333399">runnable.h<br /></em><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080"> 1</span> </font><font face="Courier New"><span style="COLOR: #000000">#ifndef RUNNABLE_H<br /></span><span style="COLOR: #008080"> 2</span> </font><font face="Courier New"><span style="COLOR: #000000">#define RUNNABLE_H<br /></span><span style="COLOR: #008080"> 3</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 4</span> </font><font face="Courier New"><span style="COLOR: #000000">struct Runnable {<br /></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">    virtual </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> run() </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span></font><font face="Courier New"><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">    virtual </span><span style="COLOR: #000000">~</span></font><font face="Courier New"><span style="COLOR: #000000">Runnable() {}<br /></span><span style="COLOR: #008080"> 7</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080"> 8</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">10</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> RunnableFunctor : </span><span style="COLOR: #0000ff">public</span></font><font face="Courier New"><span style="COLOR: #000000"> Runnable {<br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span></font><font face="Courier New"><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">    RunnableFunctor(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> T </span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">f) :_func(f) {}<br /></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">    virtual </span><span style="COLOR: #0000ff">void</span></font><font face="Courier New"><span style="COLOR: #000000"> run() { _func(); }<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">private</span></font><font face="Courier New"><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">15</span> </font><font face="Courier New"><span style="COLOR: #000000">    T _func;<br /></span><span style="COLOR: #008080">16</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">17</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">18</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">base template for no argument functor</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">19</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">20</span> </font><font face="Courier New"><span style="COLOR: #000000">struct FuncImpl {<br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> Runnable</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> transfer(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> T </span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">t) {<br /></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> RunnableFunctor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000">(t);<br /></span><span style="COLOR: #008080">23</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">24</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">25</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">26</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">partial specialization for T*</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">27</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">28</span> <span style="COLOR: #000000">struct FuncImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T </span><span style="COLOR: #000000">*&gt;</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">29</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> Runnable</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> transfer(T </span><span style="COLOR: #000000">*</span></font><font face="Courier New"><span style="COLOR: #000000">t) {<br /></span><span style="COLOR: #008080">30</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span></font><font face="Courier New"><span style="COLOR: #000000"> t;<br /></span><span style="COLOR: #008080">31</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">32</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">33</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">34</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">partial specialization for no argument function</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">35</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">36</span> <span style="COLOR: #000000">struct FuncImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T (</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)()</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">37</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> Runnable</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> transfer(T (</span><span style="COLOR: #000000">*</span></font><font face="Courier New"><span style="COLOR: #000000">t)()) {<br /></span><span style="COLOR: #008080">38</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> RunnableFunctor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T (</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)()</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000">(t);<br /></span><span style="COLOR: #008080">39</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">40</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">41</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">42</span> <span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">43</span> <span style="COLOR: #000000">inline Runnable</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> transfer(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> T </span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">t) {<br /></span><span style="COLOR: #008080">44</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> FuncImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000">::transfer(t);<br /></span><span style="COLOR: #008080">45</span> </font><font face="Courier New"><span style="COLOR: #000000">}<br /></span><span style="COLOR: #008080">46</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">47</span> <span style="COLOR: #000000">#endif</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">RUNNABLE_H</span><span style="COLOR: #008000">*/</span></font></div><br /><em style="COLOR: #333399">thread.h<br /></em><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080"> 1</span> </font><font face="Courier New"><span style="COLOR: #000000">#ifndef THREAD_H<br /></span><span style="COLOR: #008080"> 2</span> </font><font face="Courier New"><span style="COLOR: #000000">#define THREAD_H<br /></span><span style="COLOR: #008080"> 3</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">windows.h</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">bind.h</span><span style="COLOR: #000000">"</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">runnable.h</span><span style="COLOR: #000000">"</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 7</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 8</span> </font><font face="Courier New"><span style="COLOR: #000000">#define CLASS_UNCOPYABLE(classname) \<br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span></font><font face="Courier New"><span style="COLOR: #000000">: \<br /></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">    classname##(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> classname##</span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">); \<br /></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">    classname##</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000"> operator</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> classname##</span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">);<br /></span><span style="COLOR: #008080">12</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">13</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Thread : </span><span style="COLOR: #0000ff">public</span></font><font face="Courier New"><span style="COLOR: #000000"> Runnable {<br /></span><span style="COLOR: #008080">14</span> </font><font face="Courier New"><span style="COLOR: #000000">    CLASS_UNCOPYABLE(Thread)<br /></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span></font><font face="Courier New"><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">16</span> </font><font face="Courier New"><span style="COLOR: #000000">    Thread()<br /></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">        :_target(</span><span style="COLOR: #000000">0</span></font><font face="Courier New"><span style="COLOR: #000000">)<br /></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000">        ,_handle(</span><span style="COLOR: #000000">0</span></font><font face="Courier New"><span style="COLOR: #000000">) {<br /></span><span style="COLOR: #008080">19</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">20</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000">    template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">    explicit Thread(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> T </span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">op)<br /></span><span style="COLOR: #008080">23</span> </font><font face="Courier New"><span style="COLOR: #000000">        :_target(transfer(op))<br /></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000">        ,_handle(</span><span style="COLOR: #000000">0</span></font><font face="Courier New"><span style="COLOR: #000000">) {<br /></span><span style="COLOR: #008080">25</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">26</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">27</span> <span style="COLOR: #000000">    virtual </span><span style="COLOR: #000000">~</span></font><font face="Courier New"><span style="COLOR: #000000">Thread();<br /></span><span style="COLOR: #008080">28</span> <span style="COLOR: #000000">    virtual </span><span style="COLOR: #0000ff">void</span></font><font face="Courier New"><span style="COLOR: #000000"> run() {}<br /></span><span style="COLOR: #008080">29</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span></font><font face="Courier New"><span style="COLOR: #000000"> start();<br /></span><span style="COLOR: #008080">30</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span></font><font face="Courier New"><span style="COLOR: #000000"> join();<br /></span><span style="COLOR: #008080">31</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">private</span></font><font face="Courier New"><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">32</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> unsigned __stdcall threadProc(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span></font><font face="Courier New"><span style="COLOR: #000000">param);<br /></span><span style="COLOR: #008080">33</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">private</span></font><font face="Courier New"><span style="COLOR: #000000">:<br /></span><span style="COLOR: #008080">34</span> <span style="COLOR: #000000">    Runnable </span><span style="COLOR: #000000">*</span></font><font face="Courier New"><span style="COLOR: #000000">_target;<br /></span><span style="COLOR: #008080">35</span> </font><font face="Courier New"><span style="COLOR: #000000">    HANDLE _handle;<br /></span><span style="COLOR: #008080">36</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">37</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">38</span> <span style="COLOR: #000000">#endif</span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">THREAD_H</span><span style="COLOR: #008000">*/</span></font></div><br />thread.cpp和前一篇的几乎一样，唯一的不同是去掉了构造函数Thread(Runnable *)，因为现在的构造函数改成了成员模板，实现也放在thread.h中了。现在的构造函数能够接受各种类型的参数，主要归功于模板函数transfer，实现代码在runnable.h中，主要技巧是用类的偏特化模拟函数模板的偏特化，不明白的请看<a id="_117bf2a46b69_HomePageDays_DaysList_ctl00_DayItem_DayList_ctl01_TitleUrl" href="/ant/archive/2007/08/30/31201.html">为什么不要特化函数模版</a>。<br /><br />下面是测试代码：<br /><em style="COLOR: #333399">test.cpp<br /></em><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><font face="Courier New"><span style="COLOR: #008080"> 1</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">thread.h</span><span style="COLOR: #000000">"</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">functional</span><span style="COLOR: #000000">&gt;</span></font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 4</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 5</span> </font><font face="Courier New"><span style="COLOR: #000000">using namespace std;<br /></span><span style="COLOR: #008080"> 6</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">no argument function</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span></font><font face="Courier New"><span style="COLOR: #000000"> print() {<br /></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">    cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">print</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span></font><font face="Courier New"><span style="COLOR: #000000"> endl;<br /></span><span style="COLOR: #008080">10</span> </font><font face="Courier New"><span style="COLOR: #000000">}<br /></span><span style="COLOR: #008080">11</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">12</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">unary function</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">13</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> print1(</span><span style="COLOR: #0000ff">int</span></font><font face="Courier New"><span style="COLOR: #000000"> n) {<br /></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">    cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">print1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span></font><font face="Courier New"><span style="COLOR: #000000"> endl;<br /></span><span style="COLOR: #008080">15</span> </font><font face="Courier New"><span style="COLOR: #000000">}<br /></span><span style="COLOR: #008080">16</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">17</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">binary function</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">18</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> print2(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> m, </span><span style="COLOR: #0000ff">int</span></font><font face="Courier New"><span style="COLOR: #000000"> n) {<br /></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000">    cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">print2</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span></font><font face="Courier New"><span style="COLOR: #000000"> endl;<br /></span><span style="COLOR: #008080">20</span> </font><font face="Courier New"><span style="COLOR: #000000">}<br /></span><span style="COLOR: #008080">21</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">22</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">23</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">no argument functor</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">24</span> <span style="COLOR: #008000"></span></font><font face="Courier New"><span style="COLOR: #000000">struct PrintFunctor {<br /></span><span style="COLOR: #008080">25</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> operator()() </span><span style="COLOR: #0000ff">const</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">26</span> <span style="COLOR: #000000">        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">PrintFunctor</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span></font><font face="Courier New"><span style="COLOR: #000000"> endl;<br /></span><span style="COLOR: #008080">27</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">28</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">29</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">30</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">unary functor</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">31</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">struct PrintFunctor1 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> unary_function</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">32</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> operator()(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> n) </span><span style="COLOR: #0000ff">const</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">33</span> <span style="COLOR: #000000">        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">PrintFunctor1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span></font><font face="Courier New"><span style="COLOR: #000000"> endl;<br /></span><span style="COLOR: #008080">34</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">35</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">36</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">37</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">binary functor</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">38</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">struct PrintFunctor2 : </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> binary_function</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&gt;</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">39</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> operator()(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> m, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> n) </span><span style="COLOR: #0000ff">const</span></font><font face="Courier New"><span style="COLOR: #000000"> {<br /></span><span style="COLOR: #008080">40</span> <span style="COLOR: #000000">        cout </span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">PrintFunctor2</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&lt;&lt;</span></font><font face="Courier New"><span style="COLOR: #000000"> endl;<br /></span><span style="COLOR: #008080">41</span> </font><font face="Courier New"><span style="COLOR: #000000">    }<br /></span><span style="COLOR: #008080">42</span> </font><font face="Courier New"><span style="COLOR: #000000">};<br /></span><span style="COLOR: #008080">43</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">44</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span></font><font face="Courier New"><span style="COLOR: #000000"> main() {<br /></span><span style="COLOR: #008080">45</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">46</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">construct Thread with no argument function</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">47</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    Thread thread1(</span><span style="COLOR: #000000">&amp;</span></font><font face="Courier New"><span style="COLOR: #000000">print);<br /></span><span style="COLOR: #008080">48</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread1.start();<br /></span><span style="COLOR: #008080">49</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">50</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">construct Thread with unary function</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">51</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    Thread thread2(bind(ptr_fun(print1), </span><span style="COLOR: #000000">5</span></font><font face="Courier New"><span style="COLOR: #000000">));<br /></span><span style="COLOR: #008080">52</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread2.start();<br /></span><span style="COLOR: #008080">53</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">54</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">construct Thread with binary function</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">55</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    Thread thread3(bind(bind1st(ptr_fun(print2), </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">), </span><span style="COLOR: #000000">2</span></font><font face="Courier New"><span style="COLOR: #000000">));<br /></span><span style="COLOR: #008080">56</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread3.start();<br /></span><span style="COLOR: #008080">57</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">58</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">59</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">construct Thread with no argument functor</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">60</span> <span style="COLOR: #008000"></span></font><font face="Courier New"><span style="COLOR: #000000">    Thread thread4((PrintFunctor()));<br /></span><span style="COLOR: #008080">61</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread4.start();<br /></span><span style="COLOR: #008080">62</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">63</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">construct Thread with unary functor</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">64</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    Thread thread5(bind(PrintFunctor1(), </span><span style="COLOR: #000000">5</span></font><font face="Courier New"><span style="COLOR: #000000">));<br /></span><span style="COLOR: #008080">65</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread5.start();<br /></span><span style="COLOR: #008080">66</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">67</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">construct Thread with binary functor</span></font><span style="COLOR: #008000"><br /></span><font face="Courier New"><span style="COLOR: #008080">68</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    Thread thread6(bind(bind1st(PrintFunctor2(), </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">), </span><span style="COLOR: #000000">2</span></font><font face="Courier New"><span style="COLOR: #000000">));<br /></span><span style="COLOR: #008080">69</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread6.start();<br /></span><span style="COLOR: #008080">70</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">71</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread1.join();<br /></span><span style="COLOR: #008080">72</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread2.join();<br /></span><span style="COLOR: #008080">73</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread3.join();<br /></span><span style="COLOR: #008080">74</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread4.join();<br /></span><span style="COLOR: #008080">75</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread5.join();<br /></span><span style="COLOR: #008080">76</span> </font><font face="Courier New"><span style="COLOR: #000000">    thread6.join();<br /></span><span style="COLOR: #008080">77</span> </font><span style="COLOR: #000000"><br /></span><font face="Courier New"><span style="COLOR: #008080">78</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span></font><font face="Courier New"><span style="COLOR: #000000">;<br /></span><span style="COLOR: #008080">79</span> <span style="COLOR: #000000">}</span></font></div><br />当然了，上面的并不是全部，修改后的Thread类不仅能够使用原先的从Thread类继承或者实现Runnable接口的方法，还可以使用任何无参函数或无参函数对象。除了test.cpp里示范的，你甚至可以用bind,bind1st,bind2st,mem_fun,mem_fun_ref的组合来用某个类的成员函数作为参数，具有超强的灵活性。<br /><br />目前实现的这些都是Thread类最基本的功能，其他功能如设置线程优先级，挂起或恢复线程，异常处理等具体实现都比较简单，这这里就不一一实现了。 <br />源代码下载：<a href="/Files/ant/thread.rar">点击下载</a><br /><img src ="http://www.cppblog.com/ant/aggbug/31280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ant/" target="_blank">蚂蚁终结者</a> 2007-08-31 11:58 <a href="http://www.cppblog.com/ant/archive/2007/08/31/31280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++&amp;Win32写的空当接龙</title><link>http://www.cppblog.com/ant/archive/2007/08/30/31234.html</link><dc:creator>蚂蚁终结者</dc:creator><author>蚂蚁终结者</author><pubDate>Thu, 30 Aug 2007 13:37:00 GMT</pubDate><guid>http://www.cppblog.com/ant/archive/2007/08/30/31234.html</guid><wfw:comment>http://www.cppblog.com/ant/comments/31234.html</wfw:comment><comments>http://www.cppblog.com/ant/archive/2007/08/30/31234.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/ant/comments/commentRss/31234.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ant/services/trackbacks/31234.html</trackback:ping><description><![CDATA[上学期做课程设计，老师让我做windows自带的<span style="COLOR: #993300"><strong>空当接龙</strong></span>游戏，写了一个礼拜，完全仿windows的呵呵。<br>不过也不全一样，有一些细节一直没有时间弄，没办法最近比较懒...<br><br>与windows下的相比，我做的这个加入了<span style="COLOR: #993300"><strong>AI</strong><font color=#000000>(快捷键F6)，可以开启<span style="COLOR: #993300"><strong>移牌提示</strong></span>(快捷键F7)，不过<span style="COLOR: #993300"><strong>撤销</strong></span>一直没有做，可能哪天突然想做了会加上去。另外改进了<span style="COLOR: #993300"><strong>废牌回收算法</strong><font color=#000000>，非法移牌的提示直接去掉了，还有一些小的细节作了改进。<br>感兴趣的可以下载：<a title=点击下载 href="http://www.cppblog.com/Files/ant/Freecell.rar">点击下载</a><br>源代码下载：<a title=点击下载 href="http://www.cppblog.com/Files/ant/src.rar">点击下载</a><br>顺便发几张截图：<br><br><img height=479 alt="" src="http://www.cppblog.com/images/cppblog_com/ant/5051/o_4.PNG" width=642 border=0><br><img height=478 alt="" src="http://www.cppblog.com/images/cppblog_com/ant/5051/o_1.PNG" width=638 vspace=10 border=0><br><img height=480 alt="" src="http://www.cppblog.com/images/cppblog_com/ant/5051/o_2.PNG" width=639 border=0><br><br><img height=478 alt="" src="http://www.cppblog.com/images/cppblog_com/ant/5051/o_3.PNG" width=639 border=0></font></span></font></span> 
<img src ="http://www.cppblog.com/ant/aggbug/31234.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ant/" target="_blank">蚂蚁终结者</a> 2007-08-30 21:37 <a href="http://www.cppblog.com/ant/archive/2007/08/30/31234.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为什么不要特化函数模版</title><link>http://www.cppblog.com/ant/archive/2007/08/30/31201.html</link><dc:creator>蚂蚁终结者</dc:creator><author>蚂蚁终结者</author><pubDate>Thu, 30 Aug 2007 05:55:00 GMT</pubDate><guid>http://www.cppblog.com/ant/archive/2007/08/30/31201.html</guid><wfw:comment>http://www.cppblog.com/ant/comments/31201.html</wfw:comment><comments>http://www.cppblog.com/ant/archive/2007/08/30/31201.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/ant/comments/commentRss/31201.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ant/services/trackbacks/31201.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Verdana" color="#006666">Overloading vs. Specialization</font>
				<br />
				<br />在C++中有<em>class templates</em> 和<em>function templates</em>，这两种模版有很多区别，最重要的区别就是重载(overloading)：<br />普通的C++类不能重载，当然类模版也不能重载；相反，普通函数可以重载，函数模版也能重载。这再正常不过，看下面的代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080"> 1</span> <span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> Example 1: Class vs. function template, and overloading <br /></span>
						<span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 3</span> </font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 4</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> A class template</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 5</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> X { </span><span style="COLOR: #008000">/*...</span><span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> };      </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> (a)<br /></span>
						<span style="COLOR: #008080"> 6</span> </font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> A function template with two overloads</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f( T );              </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (b)</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f( </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">, T, </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> ); </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> (c)<br /></span>
						<span style="COLOR: #008080">10</span> <span style="COLOR: #008000"></span></font>
		</div>
		<p>像上面未特化的模板通常叫做<em>base templates</em>。当然，<em>base templates</em>能够被特化，在特化这一点上<br /><em>class templates</em> 和<em>function templates</em>有很大的区别：一个<em>class template</em> 能够被<em>partially specialized</em> and/or <br /><em>fully specialized</em>，一个<em>function template</em>只能被<em>fully specialized</em>，但是由于<em>function template</em>s能够重载我们可以通过重载来实现和<em>partially specialized</em> 相当的功能。下面的代码说明了这些区别：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080"> 1</span> <span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> Example 1, continued: Specializing templates <br /></span>
						<span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 3</span> </font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 4</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> A partial specialization of (a) for pointer types </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 5</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> X</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000"> { </span><span style="COLOR: #008000">/*...</span><span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> };<br /></span>
						<span style="COLOR: #008080"> 6</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> A full specialization of (a) for int </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> X</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> { </span><span style="COLOR: #008000">/*...</span><span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> };<br /></span>
						<span style="COLOR: #008080"> 9</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">10</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> A separate base template that overloads (b) and (c) <br /></span>
						<span style="COLOR: #008080">11</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> -- NOT a partial specialization of (b), because <br /></span>
						<span style="COLOR: #008080">12</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> there's no such thing as a partial specialization <br /></span>
						<span style="COLOR: #008080">13</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> of a function template! </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">14</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f( T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> );             </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> (d)<br /></span>
						<span style="COLOR: #008080">15</span> </font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">16</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> A full specialization of (b) for int </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">17</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">( </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> );              </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> (e)<br /></span>
						<span style="COLOR: #008080">18</span> </font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">19</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> A plain old function that happens to overload with <br /></span>
						<span style="COLOR: #008080">20</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> (b), (c), and (d) -- but not (e), which we'll <br /></span>
						<span style="COLOR: #008080">21</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> discuss in a moment </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">22</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f( </span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000"> );                           </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> (f)<br /></span>
						<span style="COLOR: #008080">23</span> <span style="COLOR: #008000"></span></font>
		</div>
		<p>根据函数重载解析规则：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080"> 1</span> <span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> Example 1, continued: Overload resolution <br /></span>
						<span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">bool b; <br /></span>
						<span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> i; <br /></span>
						<span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">double</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> d;<br /></span>
						<span style="COLOR: #008080"> 6</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">f( b );        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> calls (b) with T = bool </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">f( i, </span><span style="COLOR: #000000">42</span><span style="COLOR: #000000">, d ); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> calls (c) with T = int </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">f( </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">i );       </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> calls (d) with T = int </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">10</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">f( i );        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> calls (e) </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">11</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">f( d );        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> calls (f)</span></font>
		</div>
		<p>上面说的这些其实都是很简单的情况，大多数人很容易就能明白，下面的才是容易让人弄混的：<br /><br />1.考虑如下代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080"> 1</span> <span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> Example 2: Explicit specialization <br /></span>
						<span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (a) a base template </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 4</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> f( T );<br /></span>
						<span style="COLOR: #008080"> 5</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (b) a second base template, overloads (a) </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f( T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> );     </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000">     (function templates can't be partially <br /></span>
						<span style="COLOR: #008080"> 8</span> <span style="COLOR: #008000">                  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">     specialized; they overload instead)</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 9</span> <span style="COLOR: #008000"></span></font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">10</span> <span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (c) explicit specialization of (b) </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">11</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">);<br /></span>
						<span style="COLOR: #008080">12</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">13</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ...</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">14</span> <span style="COLOR: #008000"></span></font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">15</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">p; <br /></span>
						<span style="COLOR: #008080">16</span> <span style="COLOR: #000000">f( p );           </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> calls (c)</span></font>
		</div>
		<p>最后一行的结果像大多数人所期望的一样，问题是：为什么期望是这个结果？<br />如果你期望的原因是错误的，接下来的一定会让你好奇。也许你会说："我为<span style="COLOR: #3366ff">int*</span>写了一个特化版本，<span style="COLOR: #3366ff">f(p)</span>当然会调用<span style="COLOR: #3366ff">c</span>"，不幸的是，这正是错误的原因!!!<br /><br />2.再考虑下面的代码：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080"> 1</span> <span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> Example 3<br /></span>
						<span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 3</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (a) same old base template as before </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 4</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> f( T );<br /></span>
						<span style="COLOR: #008080"> 5</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (c) explicit specialization, this time of (a)</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 7</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">*</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">);<br /></span>
						<span style="COLOR: #008080"> 8</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> (b) a second base template, overloads (a) </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">10</span> <span style="COLOR: #008000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> f( T</span><span style="COLOR: #000000">*</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> );<br /></span>
						<span style="COLOR: #008080">11</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">12</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> ...</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">13</span> <span style="COLOR: #008000"></span></font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">14</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">p; <br /></span>
						<span style="COLOR: #008080">15</span> <span style="COLOR: #000000">f( p );           </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> calls (b)! overload resolution ignores <br /></span>
						<span style="COLOR: #008080">16</span> <span style="COLOR: #008000">                  </span><span style="COLOR: #008000">//</span></font>
				<font face="Courier New">
						<span style="COLOR: #008000"> specializations and operates on the base <br /></span>
						<span style="COLOR: #008080">17</span> <span style="COLOR: #008000">                  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> function templates only</span></font>
		</div>
		<p>如果这个结果让你感到惊奇，那就对了！很多人都会感到惊奇！<br />理解这个的关键是：<em style="COLOR: #993300">Specializations don't overload,only the base templates overload.<br /></em><br />重载解析仅仅选择base template(或者nontemplate function，如果有的话)，只有当编译器已经决定了哪个<br />base template将会被选择，编译器才会继续往下寻找适合的特化版本，如果找到了就使用那个特化版本。<br /><br />最后，应当避免特化函数模板，也要避免重载函数模板(nontemplate function的重载当然没问题)。如果一定要这样，可以使用如下方法模拟函数模板的偏特化：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080"> 1</span> <span style="COLOR: #008000">//</span><span style="COLOR: #008000">base template class, </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 2</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 3</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">struct FuncImpl {<br /></span>
						<span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">users, go ahead and specialize this</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080"> 5</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> apply(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> T </span><span style="COLOR: #000000">&amp;</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">t) {<br /></span>
						<span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">;<br /></span>
						<span style="COLOR: #008080"> 7</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">    }<br /></span>
						<span style="COLOR: #008080"> 8</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">};<br /></span>
						<span style="COLOR: #008080"> 9</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">10</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">partial specialazation for int</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">11</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;&gt;</span></font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">12</span> <span style="COLOR: #000000">struct FuncImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> {<br /></span>
						<span style="COLOR: #008080">13</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> apply(</span><span style="COLOR: #0000ff">int</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> t) {<br /></span>
						<span style="COLOR: #008080">14</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">;<br /></span>
						<span style="COLOR: #008080">15</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">    }<br /></span>
						<span style="COLOR: #008080">16</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">};<br /></span>
						<span style="COLOR: #008080">17</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">18</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">partial specialazation for T*</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">19</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">20</span> <span style="COLOR: #000000">    struct FuncImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T </span><span style="COLOR: #000000">*&gt;</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> {<br /></span>
						<span style="COLOR: #008080">21</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> apply(T </span><span style="COLOR: #000000">*</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">t) {<br /></span>
						<span style="COLOR: #008080">22</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">2</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">;<br /></span>
						<span style="COLOR: #008080">23</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">    }<br /></span>
						<span style="COLOR: #008080">24</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">};<br /></span>
						<span style="COLOR: #008080">25</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">26</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">users, don't touch this!</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">27</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">template </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> T</span><span style="COLOR: #000000">&gt;</span></font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">28</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> func(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> T </span><span style="COLOR: #000000">&amp;</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">t) {<br /></span>
						<span style="COLOR: #008080">29</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> FuncImpl</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T</span><span style="COLOR: #000000">&gt;</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">::apply(t);<br /></span>
						<span style="COLOR: #008080">30</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">}<br /></span>
						<span style="COLOR: #008080">31</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">32</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">10</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000">, r;<br /></span>
						<span style="COLOR: #008080">33</span> <span style="COLOR: #000000">r </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> func(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">r = 0</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">34</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">r </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> func(</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">r = 1</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">35</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">r </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> func(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">i); </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">r = 2</span></font>
		</div>
<img src ="http://www.cppblog.com/ant/aggbug/31201.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ant/" target="_blank">蚂蚁终结者</a> 2007-08-30 13:55 <a href="http://www.cppblog.com/ant/archive/2007/08/30/31201.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从Win32 API封装Thread类[1]</title><link>http://www.cppblog.com/ant/archive/2007/08/30/31190.html</link><dc:creator>蚂蚁终结者</dc:creator><author>蚂蚁终结者</author><pubDate>Thu, 30 Aug 2007 02:18:00 GMT</pubDate><guid>http://www.cppblog.com/ant/archive/2007/08/30/31190.html</guid><wfw:comment>http://www.cppblog.com/ant/comments/31190.html</wfw:comment><comments>http://www.cppblog.com/ant/archive/2007/08/30/31190.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/ant/comments/commentRss/31190.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ant/services/trackbacks/31190.html</trackback:ping><description><![CDATA[
		<p>前几天在学Windows多线程程序设计，发现Win32 API用起来确实不怎么方便，特别是对于C++程序员。于是实现了一个简单的封装，技术含量当然不高，不过用起来还是比较方便的。如果你熟悉Java，你会发现这个实现有点像Java的Thread，在Java中有两种方法可以创建一个Thread：<br /><br />1.从Thread类继承并实现run方法：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> MyThread </span><span style="COLOR: #0000ff">extends</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> Thread {<br /></span>
						<span style="COLOR: #008080">2</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> run() {<br /></span>
						<span style="COLOR: #008080">3</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">        ...<br /></span>
						<span style="COLOR: #008080">4</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">    } <br /></span>
						<span style="COLOR: #008080">5</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">};<br /></span>
						<span style="COLOR: #008080">6</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">7</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">开启线程</span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">MyThread thread </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> MyThread;<br /></span>
						<span style="COLOR: #008080">9</span> <span style="COLOR: #000000">thread.start();</span></font>
		</div>
		<p>2.声明一个类实现Runnable接口并实现run方法：</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font face="Courier New">
						<span style="COLOR: #008080">1</span> <span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> MyRunnable </span><span style="COLOR: #0000ff">implements</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> Runnable {<br /></span>
						<span style="COLOR: #008080">2</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> run() {<br /></span>
						<span style="COLOR: #008080">3</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">        ...<br /></span>
						<span style="COLOR: #008080">4</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">    }<br /></span>
						<span style="COLOR: #008080">5</span> </font>
				<font face="Courier New">
						<span style="COLOR: #000000">};<br /></span>
						<span style="COLOR: #008080">6</span> </font>
				<span style="COLOR: #000000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">7</span> <span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 开启线程 </span></font>
				<span style="COLOR: #008000">
						<br />
				</span>
				<font face="Courier New">
						<span style="COLOR: #008080">8</span> <span style="COLOR: #008000"></span><span style="COLOR: #000000">MyThread thread </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> MyThread(</span><span style="COLOR: #0000ff">new</span></font>
				<font face="Courier New">
						<span style="COLOR: #000000"> MyRunnable);<br /></span>
						<span style="COLOR: #008080">9</span> <span style="COLOR: #000000">thread.start();</span></font>
		</div>
		<br />
		<br />
		<span style="FONT-SIZE: 14pt">
				<strong>具体实现<br /></strong>
		</span>Java的实现方式还算优雅，我们也可以在C++中模拟，由于篇幅所限，在这里我们只关注基本功能的实现：<br /><span style="COLOR: #333399"><em>thread.h</em></span><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-T