﻿<?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++博客-ACG狂人-随笔分类-C++</title><link>http://www.cppblog.com/shanoa/category/10678.html</link><description>其实我更爱姐汁...</description><language>zh-cn</language><lastBuildDate>Fri, 16 Sep 2011 05:40:15 GMT</lastBuildDate><pubDate>Fri, 16 Sep 2011 05:40:15 GMT</pubDate><ttl>60</ttl><item><title>boost::asio网络传输错误码的一些实验结果（recv error_code）</title><link>http://www.cppblog.com/shanoa/archive/2011/05/06/145840.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Fri, 06 May 2011 10:06:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2011/05/06/145840.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/145840.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2011/05/06/145840.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/145840.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/145840.html</trackback:ping><description><![CDATA[错误码很重要，可以由此判断网络连接到底发生了神马事情，从而驱动高层逻辑的行为。只有笼统的错误码判断的网络层是不够规范的，鄙人觉得有些错误码还是需要在网络层就区分开的，特此记录一些当前实验的错误码以及发生原因。<br /><br />以下是一部分在async_receive()的handler处捕获到的比较有用的错误码<br />
<table style="width: 756px; border-collapse: collapse; height: 222px" border="1" cellpadding="3" cellspacing="0">
    <tbody>
        <tr>
            <td style="width: 132px">错误码（十进制）</td>
            <td style="width: 231px; height: 24px">枚举</td>
            <td>发现原因</td>
        </tr>
        <tr>
            <td>10009</td>
            <td>boost::asio::error::bad_descriptor</td>
            <td>在一个已经关闭了的套接字上执行async_receive()</td>
        </tr>
        <tr>
            <td>995</td>
            <td>boost::asio::error::operation_aborted</td>
            <td>正在async_receive()异步任务等待时，本端关闭套接字</td>
        </tr>
        <tr>
            <td>10054</td>
            <td>boost::asio::error::connection_reset</td>
            <td>正在async_receive()异步任务等待时，远端的TCP协议层发送RESET终止链接，暴力关闭套接字。常常发生于远端进程强制关闭时，操作系统释放套接字资源。</td>
        </tr>
        <tr>
            <td>2</td>
            <td>boost::asio::error::eof</td>
            <td>正在async_receive()异步任务等待时，远端关闭套接字，这里跟10054发生的情况似乎一样，但是实际上应该是有区别的，具体神马区别，由回复中jack的说法，这个是远端正常关闭套接字。</td>
        </tr>
    </tbody>
</table>
只是一些浅陋的测试，目前觉得有用的也就是这几个，不正确的地方请送我鸡蛋。<img src ="http://www.cppblog.com/shanoa/aggbug/145840.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2011-05-06 18:06 <a href="http://www.cppblog.com/shanoa/archive/2011/05/06/145840.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OGRE与MFC的文件系统冲突问题</title><link>http://www.cppblog.com/shanoa/archive/2010/12/29/137693.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Wed, 29 Dec 2010 12:49:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2010/12/29/137693.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/137693.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2010/12/29/137693.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/137693.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/137693.html</trackback:ping><description><![CDATA[<p>这两个东西在一起问题真呀么多......前些日子才写的一个注意事项的随笔，这回又有问题需要记录，好吧，开新文写。<br>问题：由于项目的复杂度，问题的表现与原因其实相差十万八千里。<br>原因：MFC在打开和保持文件后（即打开CFileDialog对话框后），就会修改进程的当前目录，就是SetCurrentDirectoy()，导致OGRE里那些用相对路径做Location的资源目录下的文件全部无法读取（其实我觉得OGRE应该把这些相对目录在读取文件的时候换成绝对目录）。具体就是openResource()中调用stat()出错，文件系统中找不到指定文件。<br>解决方法：在合适的地方调用SetCurrentDirectoy()把进程当前目录设置回进程工作目录吧......</p>
<p>于是又是一下午+半个晚上的调试时间......<br></p>
<img src ="http://www.cppblog.com/shanoa/aggbug/137693.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2010-12-29 20:49 <a href="http://www.cppblog.com/shanoa/archive/2010/12/29/137693.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>备忘随笔系列2：内存错误</title><link>http://www.cppblog.com/shanoa/archive/2010/12/23/137336.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Thu, 23 Dec 2010 15:41:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2010/12/23/137336.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/137336.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2010/12/23/137336.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/137336.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/137336.html</trackback:ping><description><![CDATA[接上文<strong>《备忘随笔系列1：MFC与OGRE联姻注意事项》</strong>之后，再记录一下内存错误，经过无数次莫名其妙的内存问题之后，发现一些找不着北的内存Crash问题出现的原因都很荒谬，所以本篇主要例举一下近期出现的一些怪异内存问题和让人啼笑皆非的原因所在。<br><br><strong>问题1：</strong>编译器在编译那些访问成员变量的代码时算错了相对于this指针的偏移字节数；赋值给下面一个变量时，却修改了上面一个变量的值。<br>原因：与我共事的某位大仙由于酷爱使用结构体传递网络包，所以在某头文件里用#pragma pack(1)包括住了整个头文件，一不小心把#include "其他头文件"那些行也给包括了进去，其中不乏Windows.h&nbsp; stl云云......<br>解决办法：当然那个啥......把#pragma pack(1)的位置往下去几行，还是细心点吧...浪费了整整一天调试。<br><br><strong>问题2：</strong>从网络另一端机器发过来一个结构体，分别接收一个结构体中的多个数据成员和一次性接收整个结构体取出的数据不同。<br>原因：这是个很2的情形，两个相同的结构体分别在不同的头文件中，且一个有#pragma pack(1)，一个没有。<br>解决办法：如果要用结构体传递网络包，还是共用头文件吧......<br><br>其实......很多内存问题很不好描述，我也不经常出现如上那样纠结的问题，所以下面我还是说一个最常见的内存问题（0x.....地址访问冲突）和原因吧：<br>&#8220;0x.....地址访问冲突&#8221;这个Crash基本上每个人都遇到，而且经常遇到，但是大部分都很容易解决。判断问题的原因可以看这几点：<br>原因1：如果0x....这个值很小，一般就比0大一些，而且是在访问某对象中的数据成员时出错的，那么这基本都是因为该对象指针为空，你用了空对象指针调用了代码。<br>原因2：如果0x...值同样很小，但是并非在访问某对象中的数据成员时出错，而是调用某函数那一行时出错的，那么这个函数十有八九是个虚函数，如果我说中的话，那原因应该如前面的原因1相同，只是这回是读取虚函数表时就崩了。<br>原因3：如果0x...值类似是0xcdcdcdcd和0xeeeccc或者与这相近的数，且同样是在访问数据成员或调用虚函数的时候出的问题，那么这就算是个野指针问题了，释放了就别再用啊。<br>原因4：内存越界，这个对程序造成的麻烦比任何麻烦都要大，但是问题并不隐蔽，记得为每个类的数据成员进行必要的初始化。<br>原因5：使用了memset或ZeroMemory清空一些对象或对象数组。特别是对象数组，很容易让人忽略这个问题。有些程序员会觉得某对象里都是可以这样清空的数据成员，所以便这样做了，但是往往虚函数表指针会被忽略，这个指针绝对不能一起被清空的。<br>总结：不要让表达索引的整形在初始化后是个未知值；不要让指针没有在初始化时被赋0值；不要不检查指针的值就拿它访问成员函数和成员数据；不要重复释放指针所指对象；不要使用释放后和未初始化的内存数据；可以的话使用智能指针；释放指针所指地址后，为指针赋0值；只有在完全是内部类型构成且没有多态的类型对象上使用memset为对象赋值。<br>
<img src ="http://www.cppblog.com/shanoa/aggbug/137336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2010-12-23 23:41 <a href="http://www.cppblog.com/shanoa/archive/2010/12/23/137336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>备忘随笔系列1：MFC与OGRE联姻注意事项</title><link>http://www.cppblog.com/shanoa/archive/2010/12/23/137249.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Wed, 22 Dec 2010 17:39:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2010/12/23/137249.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/137249.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2010/12/23/137249.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/137249.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/137249.html</trackback:ping><description><![CDATA[细节决定那啥来着，一些细节虽然不是什么难事，但是一旦卡住总是会很烦心，需要太多时间去调试，耽误的是宝贵的项目进度，所以我将在这里把一些总结贴出来，愿能给国内的游戏技术圈同僚们一点小帮助，节约宝贵的时间，毕竟总是在网络上摄取营养，算是回报社会吧。<br><br>本文记录最近发现的一些 MFC 和 OGRE1.7.2版本 联姻的注意事项：<br><br><strong>问题1：</strong>创建Ogre的CView窗口后，无法截获鼠标点击和移动信息，只能获取鼠标滚轮信息。<br>原因及解决方案：传递CView窗口句柄时，请一定使用externedWindowHandle的属性key，切记不要使用parentWindowHandle，因为parentWindowHandle是让CView成为渲染窗口的父窗口，鼠标键盘消息都不会路由到CView上，而是在渲染窗口里被截获；而externedWindowHandle是让CView窗口本身成为渲染窗口，所以CView才能正常截获到输入消息。<br><br><strong>问题2：</strong>当解决问题1之后，发现使用externedWindowHandle绘制出的窗口很小，而使用parentWindowHandle时则正常<br>原因及解决方案：注意继承CView::OnSize()函数响应WM_SIZE消息，但请切记：千万别在OnSize中调用Ogre::RenderWindow::resize()函数，这会导致OnSize()函数的递归回调，因为Ogre::RenderWindow::resize()函数中会调用AdjustWindow()和SetWindowPos()函数，这会导致发送WM_SIZE消息并缩小窗口，从而导致问题的发生。<br><br><strong>问题3：</strong>如何解决窗口重置大小的问题<br>解决方案：在OnSize()中<span style="COLOR: red"><strong>不能调用</strong></span>Ogre::RenderWindow::resize()函数，而<strong style="COLOR: red">应该调用</strong>Ogre::RenderWindow::windowMovedOrResized()函数，通知RenderWindow在渲染前重新设置Viewport的宽高比例。<br><br><strong>问题4：</strong>怎样确保主渲染循环<br>分析：上网看了一些相关的解决方案，发现大多使用WM_TIMER消息来维持OGRE的主渲染循环，这应该是下下策的方案了吧......当然还有其他的实现方案，譬如开另一个线程，这个方法还是可行的，但是总有些不对味，因为渲染明明应该在主线程中才是最佳方案。于是我就看了一下MFC闲下来的时候都干了些什么，最后发现了以下解决方案，应该算是很不错但并不难的解决办法了，为什么没见网上有人提供这样的方案让我很不理解，窝着藏着也得不到半点好处：<br>解决方案：使用空闲回调。该回调是需要继承CWinApp::OnIdle()函数（好像是叫这个，反正肯定带Idle这个单词），当主线程中的消息循环没有取到消息时（调用PeekMessage()没有获取到消息），就会去调用这个函数，于是......就在这个函数里调用绘制一帧吧：Ogre::RenderWindow::update()，另外有动画的话还需要调用Ogre::Root::_fireFrameRenderingQueued()，因为动画更新在这里。如果是想让所有渲染对象都更新一帧的话，直接调用Ogre::Root::renderOneFrame()吧。<br><br>解决方案不一定最好，也不一定适合你的情况，但愿能尽微薄之力，也是作为我个人的备忘吧。 
<img src ="http://www.cppblog.com/shanoa/aggbug/137249.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2010-12-23 01:39 <a href="http://www.cppblog.com/shanoa/archive/2010/12/23/137249.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于MVC PropertySet OperatorStack的一些设计思考</title><link>http://www.cppblog.com/shanoa/archive/2010/11/20/134166.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Sat, 20 Nov 2010 11:30:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2010/11/20/134166.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/134166.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2010/11/20/134166.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/134166.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/134166.html</trackback:ping><description><![CDATA[最近在给公司里码一个场景编辑器，大致得实现的功能有：<br>地形高度刷<br>地形纹理刷<br>放置小物件和房屋<br>放置粒子系统<br>设置路径点和只能摄像机点<br><br>算是个简单的不能再简单的场景编辑器了吧...但是这样的一个工具还是很头痛的，特别是用C++来写...<br>头痛的原因不是别的，正是这个表现层和后台数据同步问题。这个在C++的UI库中目前还真没有什么现成的好办法，于是开始造轮子，为MFC写了PropertySet和OperatorStack。<br>首先这个UI数据和内存数据双向同步的问题直接让我崩溃了...由于以前写过一些工具，知道这东西如果不做个设计就开始冲着功能写的话会有什么后果。嗯，于是继承封装了CMFCPropertyGridCtrl控件，为每个叶子属性项封装了一个LeafItem，根据属性名来更新PropertySet里对应的数据......具体实现几千字略- - 最终成型时代码这样：<br>DynamicObject obj;<br>propertyGrid.attachObject(obj);<br>这里的DynamicObject继承PropertySet，于是propertyGrid控件就会显示obj里所有的属性数据了...然后是双向更新问题，目前是给Property里加了一个eventValueChanged事件响应，让PropertyGridCtrl监听这些数据的变化，而propertyGridCtrl这个UI上的数据变化同样是派生实现CMFCPropertyGridCtrl的值变化响应函数来给绑定的LeafItem更新数据，也是直接就刷新到Property里了。<br>还有OperatorStack.....这个是操作栈，记录用户操作的，用于撤销和重做的操作，也用到了PropertySet来记录变化对象的属性快照，嗯，叫SnapShootRecord的类里面记录的都是一个对象的变化属性。<br>先就记录这么多，很乱很不容易懂，主要给我自己做个记录的，没啥贡献，实际上还有很多不好用的地方，所以最近在想一些改进设计，等我想好了放上来详细设计和源码吧.......<img src ="http://www.cppblog.com/shanoa/aggbug/134166.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2010-11-20 19:30 <a href="http://www.cppblog.com/shanoa/archive/2010/11/20/134166.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>终于完成了自己的模板设计，初步实现了filter_streambuf，cge项目启动......</title><link>http://www.cppblog.com/shanoa/archive/2010/10/12/129640.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Tue, 12 Oct 2010 11:37:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2010/10/12/129640.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/129640.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2010/10/12/129640.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/129640.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/129640.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">实现的目的是为了在一些特定情况下不去使用boost的filter_streambuf，不使用boost::iostreams的理由如下：<br>1、基于运行时配置的过滤器，效率稍低<br>2、对于网络通讯而言，boost的filter_streambuf乃至整个iostreams库都显得较为臃肿。<br>所以，我自己编写了一套filter_streambuf，继承了std::streambuf，并配合自己重新设计的archive和batch_data进行网络通讯，无论是效率还是易用性上都超出使用boost的iostreams。而boost的那套东西经过我的反复使用后，觉得更适合用在文件读写和数据持久化上。<br>如果要说哪里不如boost的filter_stream，也就是boost的filter_streambuf可以动态配置filter，而我使用的是模板技术将filter的关系在编译期就关联了起来，所以只能是静态配置filter。下面是具体使用时的完整例子代码：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><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">ccs</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">util</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">ios</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">ifilter_streambuf.hpp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><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">ccs</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">util</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">ios</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">ofilter_streambuf.hpp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><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">ccs</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">util</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">ios</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">memory_terminal.hpp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;ccs;<br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;util;<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;输出过滤</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;my_ofilter<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ios::ofilter_tag&nbsp;tag_type;<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;OutT</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::streamsize&nbsp;write(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p,&nbsp;std::streamsize&nbsp;n,&nbsp;OutT</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_out)<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::streamsize&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><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;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;n;&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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">char</span><span style="COLOR: #000000">&nbsp;c&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;p[i];<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;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(_out.write(</span><span style="COLOR: #000000">&amp;++</span><span style="COLOR: #000000">c,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><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;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;i;<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;输入过滤</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;my_ifilter<br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ios::ifilter_tag&nbsp;tag_type;<br></span><span style="COLOR: #008080">31</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">32</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;InT</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">33</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::streamsize&nbsp;read(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p,&nbsp;std::streamsize&nbsp;n,&nbsp;InT</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_in)<br></span><span style="COLOR: #008080">34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::streamsize&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;n;&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br></span><span style="COLOR: #008080">37</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">38</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;c;<br></span><span style="COLOR: #008080">39</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;(_in.read(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">c,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">40</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: #0000ff">break</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p[i]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">c;<br></span><span style="COLOR: #008080">42</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">43</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;i;<br></span><span style="COLOR: #008080">44</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">45</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">46</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">47</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;输出内存设备</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">48</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;memory_odevice<br></span><span style="COLOR: #008080">49</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">50</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ios::dest_tag&nbsp;tag_type;<br></span><span style="COLOR: #008080">51</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">52</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::streamsize&nbsp;write(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p,&nbsp;std::streamsize&nbsp;n,&nbsp;ios::memory_oterminal</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_out)<br></span><span style="COLOR: #008080">53</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">54</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;_out.write(p,&nbsp;n);<br></span><span style="COLOR: #008080">55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">56</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">57</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">58</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;输入内存设备</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">59</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;memory_idevice<br></span><span style="COLOR: #008080">60</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;ios::source_tag&nbsp;tag_type;<br></span><span style="COLOR: #008080">62</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::streamsize&nbsp;read(</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p,&nbsp;std::streamsize&nbsp;n,&nbsp;ios::memory_iterminal</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;_in)<br></span><span style="COLOR: #008080">64</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">65</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;_in.read(p,&nbsp;n);<br></span><span style="COLOR: #008080">66</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">67</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">68</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">69</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">70</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">**</span><span style="COLOR: #000000">&nbsp;_Args)<br></span><span style="COLOR: #008080">71</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">72</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;buf[</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">];<br></span><span style="COLOR: #008080">73</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ios::memory_oterminal&nbsp;memout(buf,&nbsp;</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">74</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ios::memory_iterminal&nbsp;memin(buf,&nbsp;</span><span style="COLOR: #000000">256</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">75</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ios::ifilter_streambuf</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ios::memory_iterminal,&nbsp;mpl::list2</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">my_ifilter,&nbsp;memory_idevice</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;insbuf(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">memin);<br></span><span style="COLOR: #008080">76</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ios::ofilter_streambuf</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ios::memory_oterminal,&nbsp;mpl::list2</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">my_ofilter,&nbsp;memory_odevice</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;outsbuf(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">memout);<br></span><span style="COLOR: #008080">77</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::istream&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">insbuf);<br></span><span style="COLOR: #008080">78</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::ostream&nbsp;os(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">outsbuf);<br></span><span style="COLOR: #008080">79</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">80</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;num&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">188</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">81</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;os.write((</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">num,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">));<br></span><span style="COLOR: #008080">82</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;os.flush();<br></span><span style="COLOR: #008080">83</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">.read((</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">num,&nbsp;</span><span style="COLOR: #0000ff">sizeof</span><span style="COLOR: #000000">(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">));<br></span><span style="COLOR: #008080">84</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">85</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;num&nbsp;</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">&nbsp;std::endl;<br></span><span style="COLOR: #008080">86</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pause</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">87</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<p>代码中的意思就是将写入的数据逐字节的加1，并保存在内存缓冲里，然后又从内存缓冲中读出，逐字节减1，并输出到控制台，一套经过过滤的读写流便完成了。由于使用了模板元的list作为链接，在release模式下所有的过滤器操作都是内联的，这虽然也是我预想的效果，但看完汇编码之后，着实让我高兴了一晚上，这种成就感真的是programer最大的乐趣。</p>
<p>需要说明的是：代码中的mpl::list2是自己实现的模板元链表...过段时间考虑研究一下boost的并替换过来，因为那个list后面的2让我觉得很不够智能...当然，如果boost的list实现过于复杂，或是不能让我的代码完全内联化的话，肯定不会考虑使用。<br><br>完成这个之后，我便准备着手构建cge项目，所谓的cge，就是cloud game engine的缩写...顾名思义就是使用了云技术的游戏引擎，我想在业余时间尝试一些颠覆传统cs架构的在线游戏引擎架构设计，具体难点估计会有2个：<br>1、运用gpgpu group的并行运算技术，考虑使用目前市场占用率最大的nvidia tesla服务器配合cuda，在服务器用physX实现一定的物理模拟。<br>2、在即时性较强的在线游戏中，ping值一直是最大的挑战，所以有选择性的使用云计算技术，这是架构设计上的挑战。<br>关于cge的设计思考和规划，会另外开贴具体阐述，并记录开发进度和情况。</span></p>
<img src ="http://www.cppblog.com/shanoa/aggbug/129640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2010-10-12 19:37 <a href="http://www.cppblog.com/shanoa/archive/2010/10/12/129640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>析构过程中内存相关错误的绝大多数原因</title><link>http://www.cppblog.com/shanoa/archive/2010/07/01/119064.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Thu, 01 Jul 2010 07:47:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2010/07/01/119064.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/119064.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2010/07/01/119064.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/119064.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/119064.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">今天记录一下长久以来屡次犯的错，每次都是换一种方法编码来绕过这个问题实现功能的，因为这个问题太过隐蔽，导致今天才发现其中真正的原因...下面进行问题描述：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">std::map</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">std::</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">,&nbsp;Value</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;keyValue;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;在函数内部分配的堆栈对象（局部变量）</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">2</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">ReadData(keyValue);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;从dll中导出的函数</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">3</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">keyValue.clear();&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;delete中出现assert异常</span></div>
<br>第一行是在应用程序中的堆栈中分配的内存空间。<br>第二行是我自己写的dll库，用来读取一些数据加入到keyValue中。<br>第三行是清空keyValue，其实如果不写这一行的话，keyValue也会在函数结尾时清空，到那时同样会出现错误。<br>这一切乍一看没啥问题，keyValue是局部变量，为什么局部变量的释放会出现异常错误呢？这是因为第二行ReadData的缘故。ReadData的逻辑在另外一个可执行模块中，在其中分配的内存空间不一定与当前模块在同一个堆区。<br>我们知道，std::map是一个树结构的容器，我在ReadData内部往keyValue中添加了数据，keyValue中会在堆区中分配树节点，而这个节点将会在当前模块在keyValue的析构中被释放。也就是说，我无意中在dll模块中分配了堆空间，又无意中在exe模块中企图释放该空间，这样的行为导致错误是不足为怪的。<br><span style="COLOR: red"><strong style="FONT-FAMILY: 黑体">时刻牢记，在一个模块中分配和释放同一块内存区域，警惕你所看不见的内存分配和释放。</strong></span></span>
<img src ="http://www.cppblog.com/shanoa/aggbug/119064.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2010-07-01 15:47 <a href="http://www.cppblog.com/shanoa/archive/2010/07/01/119064.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>完成的网络数据包文档化</title><link>http://www.cppblog.com/shanoa/archive/2010/04/24/113460.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Sat, 24 Apr 2010 12:34:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2010/04/24/113460.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/113460.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2010/04/24/113460.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/113460.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/113460.html</trackback:ping><description><![CDATA[<p>好久没写blog了，这次初步完成了一个文档化的网络流框架，这玩意儿是咱自己这样叫，但具体是啥玩意儿呢？其实就是将网络通讯数据结构给串行化到缓冲里，再发送到网络的另一端，由另一端再串行化到相应的类型对象里。恩，这听起来没啥难度呀，但事实并非如此，呵呵，该架构建立在asio基础之上，目前完成了tcp通讯部分，基本可以很方便的使用了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为啥我要写这么个架子，因为网络通讯需要考虑很多情况，如粘包、未接收完整、缓冲不够大等情况，而且在项目开发过程中，不断的添加和修改一些通信协议相关的数据包结构。为了让程序员不要管那么多麻烦的情况，同时易于修改和添加新的通讯协议，于是就写了这么个架构，不过今天比较忙，还是下次传上用例代码吧，源码可能会在不久以后发布的通用库模板库里找到。<br>恩，咱要发布自己的一个开源库，建立在stl和boost基础上，可跨平台编译 0 0......<br>到时候再说了。</p>
<img src ="http://www.cppblog.com/shanoa/aggbug/113460.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2010-04-24 20:34 <a href="http://www.cppblog.com/shanoa/archive/2010/04/24/113460.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>封装MySQL时解决的两个字符集问题</title><link>http://www.cppblog.com/shanoa/archive/2009/10/09/98199.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Fri, 09 Oct 2009 14:29:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/10/09/98199.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/98199.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/10/09/98199.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/98199.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/98199.html</trackback:ping><description><![CDATA[在我开始封装MySQL C API时，真的没有想过居然会在字符集问题上连续卡壳，折腾了一下午+一晚上，终于搞定这些问题。下面记录一下我遇见的问题以及解决办法，以作备忘。<br>首先遇见的当然是中文乱码问题。这个问题相对来说资料比较多，文档写得应该也是很清楚的，但是我没心思看，靠猜搞定。我首先设置MySQL服务器的默认字符集为UTF8，并保证我操作的表中的列字符集也是UTF8，然后重启MySQL服务，并尝试用mysql_query("INSERT INTO TestTable VALUES('你好')")来写入，结果失败在预料之中。我猜可能可以使用类似"INSERT INTO TestTable VALUES('\0x2734\0x3432')"这样的方式写入中文，但这样太丑了，也没有实用价值，我坚决不会去用。我又尝试使用MultiByteToWideChar去做，甚至使用了Qt的QTextCodec去转换&#8220;你好&#8221;这两个字，结果依然失败。这就有些蹊跷了，我决定调用mysql_character_set_name()看看到底有没有正确的设置成UTF8格式，让我意料之外的是：结果是latin1，这难道是拉丁字符集？？我查看了一下API函数的相关说明，发现这里获取到的是客户端链接的字符集，我突然觉得，也许MySQL可以自动的在客户端与服务器之间的字符集进行转化！说做就做，我查到了可以用mysql_options()或者mysql_set_character_name()函数来设置客户端链接字符集，但这两个函数用的时机分别在调用mysql_real_connect()之前或之后。我将客户端链接设置成gb2312字符集，这是VC中支持中文的标准字符集之一（另一个标准是UTF16，需要用wchar_t&nbsp; wstring和常量字符串前的L），结果，当然是非常正确的插入中文啦，呵呵！<br>正当我觉得下面的封装肯定会顺汤顺水之时，在封装基本完成的时候，我发现控制台不能输出我从MySQL取出的中文了！这太奇怪了，输出英文就没有问题，而中文虽然的确被准确无误的读入了std::string中（通过单步调试和ofstream得到确认），然而输出到cout中却会出错。为什么文件流没问题，控制台流会出问题呢？我跟踪了代码，发现在fputc()函数中出现了问题。另一个奇特的地方，就是在mysql_init()函数被调用之前，cout可以正确输出中文，但调用之后就不能输出，iostate被赋予4值，即badbit。我求了一下google，发现sputc()中的一个_nolock_write()函数是msvcrtd.lib中的函数，晕了，我在单步调试中也发现就是这里有问题，确切的说，mysql_init()函数被调用后，_nolock_write()函数就会出错。哈哈，总结出了这些特点之后，我已经隐约猜到了是哪里的问题了，还记得前几日才写的blog里的东西，我由于想要将libmysql.lib换成mysqlclient.lib静态库，所以便禁掉了msvcrtd.lib库，我肯定这里面有关联。<br>到底是什么原因呢？我觉得，由于这个MySQL的SDK不是我自己编译的，mysqlclient.lib里面调用crt函数时，对字符集的本地化做了设置，由于是欧美的字符集设置，所以一旦我调用了mysqlclient.lib里的函数，就无法再显示中文了。<br>猜出了问题的根源，那么如何解决这个问题呢？我可以肯定的是，使用std::cout.imbue(std::locale())是行不通的，那么下面就是列出的几个办法：<br>1、使用人家编译好的动态库，libmysql.lib，并将libmysql.dll拷贝过来，由于动态库和你的程序共享crt dll，因此字符集设置应该会是一致的。<br>2、如果你还是想用静态库，可以考虑自己下载源码并编译一遍，这是根本的解决办法。<br>3、如果你可以自己编译，且想用mysqlclient.lib，那么就重新编译mysqlclient吧，动态静态都可以。不过官网上下载的编译好的mysqlclient.lib是静态的，不能使用。<br><br>我最终的解决办法是第1种，因为比较懒，不想自己再去编译了，呵呵。
<img src ="http://www.cppblog.com/shanoa/aggbug/98199.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-10-09 22:29 <a href="http://www.cppblog.com/shanoa/archive/2009/10/09/98199.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>原来静态库是这样链接的</title><link>http://www.cppblog.com/shanoa/archive/2009/10/06/97972.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Tue, 06 Oct 2009 13:30:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/10/06/97972.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/97972.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/10/06/97972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/97972.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/97972.html</trackback:ping><description><![CDATA[最近在win32平台下封装MySQL的客户端C API时，出现的问题着实让我头痛了个把小时，不过多亏这一来，我终于明白了静态库是怎样链接的，结合了以前我对动态库与静态库之间进行比较的一些测试结论，也明白了为什么静态库需要这样的设计。不由感叹一下古人的那句话：&#8220;挫折果真是成功的母亲。&#8221;（好大雾^_^!）<br>闲话不多说，记录一些关键点，首先是静态链接到底和动态链接有哪些不太容易发现的区别呢？我来假设libA依赖libB，那么我的执行文件在使用libA的时候也需要导入libB才能正确链接，但若dllA依赖libB的话，则只需导入dllA就可以。我在一开始用MySQL时使用的内嵌数据库模式，所以导入的是那个libmysql.dll动态库，因此没出现问题。而换上了mysqlclient.lib后，居然告诉我没有找到socket相关的实现，即&#8220;无法解析的外部符号&#8221;这类错误，于是乎我只有加上ws2_32.lib库才能通过。<br>为什么这样设计？原因其实跟静态库的连接方式有关，由于静态库直接将函数实现和全局静态变量导入到包含它的执行体中，所以在多层多重的库包含中就会有大量重定义的问题存在，想想你在一个静态库中用了单件模式，那么其他库又包含你这个库，最后exe又包含所有这些库，最终形成菱形依赖，如果静态库不这样设计的话，问题就会像C++的多重继承问题一样。之所以静态库这样设计，跟C++的虚拟继承思想简直如出一辙。（我知道这段话其实只有已经懂了的人才能看得懂，不过没办法，我表达能力挺笨的...）<br><br>还有个极度郁闷的地方是：mysqlclient.lib中的libcmtd.lib和msvcrtd.lib这对活宝居然也被链接进去了，我这边首先需要忽略这两个默认库，然后再包含msvcrtd.lib才可以。我不知道为啥sdk提供的静态库非得在c runtime link的方式上跟一般人过不去，又懒得去自己编译，哎！将就一下就这么用吧...... 
<img src ="http://www.cppblog.com/shanoa/aggbug/97972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-10-06 21:30 <a href="http://www.cppblog.com/shanoa/archive/2009/10/06/97972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>异常处理的可恶陷阱</title><link>http://www.cppblog.com/shanoa/archive/2009/08/02/91967.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Sun, 02 Aug 2009 09:12:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/08/02/91967.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/91967.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/08/02/91967.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/91967.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/91967.html</trackback:ping><description><![CDATA[也许这个错误是很幼稚的，但是他着实难住了我好几个小时，一度我还以为永远解不开这个谜题了(*o*)，情况是这样的，异常在抛出之后，到达处理异常的catch域，但这时上下文必须依然有效才行，否则catch将接收不到抛出的异常。具体代码如下：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_6_454_Open_Image onclick="this.style.display='none'; Codehighlighter1_6_454_Open_Text.style.display='none'; Codehighlighter1_6_454_Closed_Image.style.display='inline'; Codehighlighter1_6_454_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_6_454_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_6_454_Closed_Text.style.display='none'; Codehighlighter1_6_454_Open_Image.style.display='inline'; Codehighlighter1_6_454_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_6_454_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_6_454_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;moeutil::simple_pool&nbsp;spool(</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;spool.malloc(</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;spool.malloc(</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p3&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;spool.malloc(</span><span style="COLOR: #000000">15</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p4&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;spool.malloc(</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p5&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;spool.malloc(</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p6&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;spool.malloc(</span><span style="COLOR: #000000">70</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">std::cout&lt;&lt;p1&lt;&lt;'\n'&lt;&lt;p2&lt;&lt;'\n'&lt;&lt;p3&lt;&lt;'\n'&lt;&lt;p4&lt;&lt;'\n'&lt;&lt;p5&lt;&lt;'\n'&lt;&lt;p6&lt;&lt;std::endl;</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spool.free(p1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spool.free(reinterpret_cast</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">(p2)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spool.free(p3);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spool.free(p4);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spool.free(p5);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spool.free(p6);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_484_521_Open_Image onclick="this.style.display='none'; Codehighlighter1_484_521_Open_Text.style.display='none'; Codehighlighter1_484_521_Closed_Image.style.display='inline'; Codehighlighter1_484_521_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_484_521_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_484_521_Closed_Text.style.display='none'; Codehighlighter1_484_521_Open_Image.style.display='inline'; Codehighlighter1_484_521_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">&nbsp;(moeutil::Exception</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;e)</span><span id=Codehighlighter1_484_521_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_484_521_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">e.what()</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
这是一个简易的内存池类，其中simple_pool的析构函数会抛出异常，然后free函数也会抛出异常。析构函数可以检测是否有内存泄漏，而free函数是检测到无效的传入指针时会抛出异常。析构抛出异常是没问题的，但是free抛出异常的时候问题就来了，当free抛出异常时，由于会脱离try块，所以spool也会被析构，这样就会陷入麻烦，由于没有全部free，所以析构本身也会抛出异常，导致了类似于异常迭代的情况。也就是说，在throw一个异常的过程中又一次触发了异常。于是windows系统的debug error对话框出现了，而且是出现在throw那一行。<br>此随笔用于提醒自己勿犯第二次！
<img src ="http://www.cppblog.com/shanoa/aggbug/91967.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-08-02 17:12 <a href="http://www.cppblog.com/shanoa/archive/2009/08/02/91967.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用boost库需要一定的素质</title><link>http://www.cppblog.com/shanoa/archive/2009/07/30/91733.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Thu, 30 Jul 2009 10:19:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/07/30/91733.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/91733.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/07/30/91733.html#Feedback</comments><slash:comments>22</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/91733.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/91733.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可能由于在几个博客上发布了一些boost库使用心得的关系，最近总是被一些相关的询问邮件骚扰，而提问者问的问题却又让我不知道如何回答才好，或者说根本没有办法回答。一些问题根本就不该问的，所以便发些感慨，还望看了本人一些心得又不禁想问一些偷懒问题的各位手下留情，不要再问我一些奇怪的问题了(*w*)!<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们学习并使用boost库的目的是简化编程，这并不代表简化到你根本不需要去理解原理的地步。我想，如果您希望很好的驾驭boost库的话，那么请对您自己发发狠努力编写代码积累经验，直到您认为boost库中30%的功能您都能够亲自动手实现的时候，才尝试去使用它。类似&#8220;怎么让线程组和asio合作使用&#8221;之类的问题，我觉得很囧，而且问的人还非常多，给代码都还迷糊。我觉得您想用asio，请先尝试编写线程类和IOCP框架的应用程序，如果您连线程类都写不好，或者连一个多线程死锁和共享区都不能安全排除的话，请先打打基础吧。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boost库是一个非常有深度的东西，也是智慧的结晶，有很多东西在一定条件下您可以不用深究，但是起码的30%则必须刨根问底，这30%实际上都是很基础的东西，切不可急于一时而至整个工程最终因为boost的一点小问题卡壳，倘若无法驾驭，则不如不用，再急我也没法帮您了！</p>
<img src ="http://www.cppblog.com/shanoa/aggbug/91733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-07-30 18:19 <a href="http://www.cppblog.com/shanoa/archive/2009/07/30/91733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC编译器中的一些编译时命令备忘</title><link>http://www.cppblog.com/shanoa/archive/2009/07/30/91730.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Thu, 30 Jul 2009 10:00:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/07/30/91730.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/91730.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/07/30/91730.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/91730.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/91730.html</trackback:ping><description><![CDATA[<p>&nbsp;</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"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;加载静态库</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">#pragma&nbsp;comment(lib,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">路径+LIB库名</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;禁止1221号警告</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">#pragma&nbsp;warning(disable:&nbsp;</span><span style="COLOR: #000000">1221</span><span style="COLOR: #000000">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;导入并加载DLL&nbsp;exe之类的二进制动态库</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">#import&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">路径+二进制库名</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;将ClassName类中的s_Data静态成员变量定义在头文件中时防止重定义</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">__declspec(selectany)&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;ClassName::s_Data&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;当用户使用void&nbsp;func()函数时，编译器将作出警告，并显示&#8220;不推荐使用该函数&#8221;字样</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">__declspec(deprecated(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">不推荐使用该函数</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">))&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func();</span></div>
<img src ="http://www.cppblog.com/shanoa/aggbug/91730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-07-30 18:00 <a href="http://www.cppblog.com/shanoa/archive/2009/07/30/91730.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>记录一下C++标准流感悟</title><link>http://www.cppblog.com/shanoa/archive/2009/07/29/91647.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Wed, 29 Jul 2009 15:46:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/07/29/91647.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/91647.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/07/29/91647.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/91647.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/91647.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 今天终于完成了自己的日志库核心的几个类和算法，折腾了许久，感觉安全性很好，一些多线程的死锁问题已经逐个排除了。由于需要跟C++标准库的输入输出流共事，所以么总算自认为理解了C++标准流的一些特性，记下来以供备忘。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先是文件流，关于该流的问题，要扯就扯远了，主要说一说std::wofstream的问题。不要被这个w骗了，其实它输出到文件上的依然还是那么回事，没有丝毫的变化。如果你是想输出Unicode到文本文件中，那么你最好是用ios::binary模式，然后一股脑的倒入文件中，如果要是使用&lt;&lt;重载符号的话，输出到文件中的跟std::ofstream没区别，而且中文还无法输出。如果你遇见中文无法输出的问题，恩，可以调用std::wofstream::imbue()方法，具体也就是一行：ofs.imbue(std::locale("chs"));搞定。<br>我想，C++标准库并不支持Unicode编码，而是给字符地域化的编码方式，中文的可能也就是GBK吧，听说C++0x标准会纳入Unicode编码支持，如果是这样的话就省心多了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 然后还有个不省心的地方就是流的streambuf中的缓冲大小了，我发现，fstream中的写缓冲居然一直是0啊，这个就很头疼了，需要给文件流指定缓冲的大小。</p>
<img src ="http://www.cppblog.com/shanoa/aggbug/91647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-07-29 23:46 <a href="http://www.cppblog.com/shanoa/archive/2009/07/29/91647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASIO攻破！！！</title><link>http://www.cppblog.com/shanoa/archive/2009/06/26/88606.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Fri, 26 Jun 2009 14:14:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/06/26/88606.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/88606.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/06/26/88606.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/88606.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/88606.html</trackback:ping><description><![CDATA[花了足足3天时间，外加1天心情休整，终于在第5天编写出了一个能运行的基于asio和thread_group的框架，差点没气晕过去，把源码都看懂了才感觉会用了。<br>测试了一下，debug下一万次回应耗时800+毫秒，release下是200+毫秒，机器配置双核2.5G英特尔，4个线程并行工作，无错的感觉真好，再也不用担心iocp出一些奇怪的问题啦，因为是巨人们写的实现，呵呵。<br><br>进入正题，简要说一下asio的实现原理吧。在win32平台上，asio是基于IOCP技术实现的，我以前也用过IOCP，却没想到居然能扩展成这样，真是神奇！在其他平台下还会有别的方法去实现，具体见io_service类下面这部分的源码：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;The&nbsp;type&nbsp;of&nbsp;the&nbsp;platform-specific&nbsp;implementation.</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#if</span><span style="COLOR: #000000">&nbsp;defined(BOOST_ASIO_HAS_IOCP)</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;typedef&nbsp;detail::win_iocp_io_service&nbsp;impl_type;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;friend&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;detail::win_iocp_overlapped_ptr;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#elif</span><span style="COLOR: #000000">&nbsp;defined(BOOST_ASIO_HAS_EPOLL)</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;typedef&nbsp;detail::task_io_service</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">detail::epoll_reactor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;impl_type;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#elif</span><span style="COLOR: #000000">&nbsp;defined(BOOST_ASIO_HAS_KQUEUE)</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;typedef&nbsp;detail::task_io_service</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">detail::kqueue_reactor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;impl_type;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#elif</span><span style="COLOR: #000000">&nbsp;defined(BOOST_ASIO_HAS_DEV_POLL)</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;typedef&nbsp;detail::task_io_service</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">detail::dev_poll_reactor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;impl_type;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;typedef&nbsp;detail::task_io_service</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">detail::select_reactor</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;impl_type;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
这部分代码其实就在boost::asio::io_service类声明中的最前面几行，可以看见在不同平台下，io_service类的实现将会不同。很显然，windows平台下当然是win_iocp_io_service类为实现了（不过我一开始还以为win_iocp_io_service是直接拿出来用的呢，还在疑惑这样怎么有移植性呢？官方文档也对该类只字不提，其实我卡壳就是卡在这里了，差点就直接用这个类了^_^!）。<br><br>那么就分析一下win_iocp_io_service的代码吧，这里完全是用IOCP来路由各种任务，大家使用post来委托任务，内部调用的其实是IOCP的PostQueuedCompletionStatus函数，然后线程们用run来接受任务，内部其实是阻塞在IOCP的GetQueuedCompletionStatus函数上，一旦有了任务就立即返回，执行完后再一个循环，继续阻塞在这里等待下一个任务的到来，这种设计思想堪称神奇，对线程、服务以及任务完全解耦，灵活度达到了如此高度，不愧为boost库的东西！我只能有拜的份了...<br><br>说一下总体的设计思想，其实io_service就像是劳工中介所，而一个线程就是一个劳工，而调用post的模块相当于富人们，他们去中介所委托任务，而劳工们就听候中介所的调遣去执行这些任务，任务的内容就写在富人们给你的handler上，也就是函数指针，指针指向具体实现就是任务的实质内容。其实在整个过程中，富人们都不知道是哪个劳工帮他们做的工作，只知道是中介所负责完成这些就可以了。这使得逻辑上的耦合降到了最低。不过这样的比喻也有个不恰当的地方，如果硬要这样比喻的话，我只能说：其实劳工里面也有很多富人的^o^! 。很多劳工在完成任务的过程中自己也托给中介所一些任务，然后这些任务很可能还是自己去完成。这也难怪，运行代码的总是这些线程，那么调用post的肯定也会有这些线程了，不过不管怎么说，如此循环往复可以解决问题就行，比喻不见得就得恰当，任何事物之间都不可能完全相同，只要能阐述思想就行。<br><br>最后还要说明的一点就是：委托的任务其实可以设定执行的时间的，很不错的设定，内部实现则是通过定时器原理，GetQueuedCompletionStatus有一个等待时间的参数似乎被用在这方面，还有源码中的定时器线程我并没有过多的去理解，总之大体原理已基本掌握，剩下的就是使劲的用它了！！！<br><br>另外为了方便人交流，在这里插入一些代码可能更容易让人理解吧，<br>下面这个是启动服务时的代码：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ServerFramework::run()<br><img id=Codehighlighter1_28_210_Open_Image onclick="this.style.display='none'; Codehighlighter1_28_210_Open_Text.style.display='none'; Codehighlighter1_28_210_Closed_Image.style.display='inline'; Codehighlighter1_28_210_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_28_210_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_28_210_Closed_Text.style.display='none'; Codehighlighter1_28_210_Open_Image.style.display='inline'; Codehighlighter1_28_210_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_28_210_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_28_210_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;boost::thread_group&nbsp;workers;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(uint32&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;mWorkerCount;&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">i)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;workers.create_thread(<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">boost::asio::io_service::run,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">mIoService));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;workers.join_all();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>在打开前就得分配好任务，否则线程们运行起来就退出了，阻塞不住，任务的分配就交给open函数了，它是分配了监听端口的任务，一旦有了连接就会抛出一个任务，其中一个线程就会开始行动啦。<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_86_111_Open_Image onclick="this.style.display='none'; Codehighlighter1_86_111_Open_Text.style.display='none'; Codehighlighter1_86_111_Closed_Image.style.display='inline'; Codehighlighter1_86_111_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_86_111_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_86_111_Closed_Text.style.display='none'; Codehighlighter1_86_111_Open_Image.style.display='inline'; Codehighlighter1_86_111_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ServerFramework::open(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;String</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;address,&nbsp;</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;String</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;port,&nbsp;uint32&nbsp;nWorkers&nbsp;</span><span id=Codehighlighter1_86_111_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_86_111_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">=&nbsp;DEFAULT_WORKER_COUNT</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000">)<br><img id=Codehighlighter1_114_824_Open_Image onclick="this.style.display='none'; Codehighlighter1_114_824_Open_Text.style.display='none'; Codehighlighter1_114_824_Closed_Image.style.display='inline'; Codehighlighter1_114_824_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_114_824_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_114_824_Closed_Text.style.display='none'; Codehighlighter1_114_824_Open_Image.style.display='inline'; Codehighlighter1_114_824_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_114_824_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_114_824_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Open&nbsp;the&nbsp;acceptor&nbsp;with&nbsp;the&nbsp;option&nbsp;to&nbsp;reuse&nbsp;the&nbsp;address&nbsp;(i.e.&nbsp;SO_REUSEADDR).</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;boost::asio::ip::tcp::resolver&nbsp;resolver(mIoService);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;boost::asio::ip::tcp::resolver::query&nbsp;query(address,&nbsp;port);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;boost::asio::ip::tcp::endpoint&nbsp;endpoint&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">resolver.resolve(query);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mAcceptor.open(endpoint.protocol());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mAcceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mAcceptor.bind(endpoint);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mAcceptor.listen();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mNextConnection&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Connection(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mAcceptor.async_accept(mNextConnection</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">getSocket(),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">ServerFramework::__onConnect,&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::asio::placeholders::error));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mWorkerCount&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;nWorkers;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(mWorkerCount&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;DEFAULT_WORKER_COUNT)<br><img id=Codehighlighter1_799_822_Open_Image onclick="this.style.display='none'; Codehighlighter1_799_822_Open_Text.style.display='none'; Codehighlighter1_799_822_Closed_Image.style.display='inline'; Codehighlighter1_799_822_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_799_822_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_799_822_Closed_Text.style.display='none'; Codehighlighter1_799_822_Open_Image.style.display='inline'; Codehighlighter1_799_822_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_799_822_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_799_822_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mWorkerCount&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>open函数中给io_service的一个任务就是在有链接访问服务器端口的情况下执行ServerFramework::__onConnect函数，有一点需要格外注意的，io_service必须时刻都有任务存在，否则线程io_service::run函数将返回，于是线程都会结束并销毁，程序将退出，所以，你必须保证无论何时都有任务存在，这样线程们即使空闲了也还是会继续等待，不会销毁。所以，我在ServerFramework::__onConnect函数中又一次给了io_service相同的任务，即：继续监听端口，有链接了还是调用ServerFramework::__onConnect函数。如果你在ServerFramework::__onConnect执行完了还没有给io_service任务的话，那么一切都晚了...... 代码如下：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;ServerFramework::__onConnect(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;BoostSysErr</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;e)<br><img id=Codehighlighter1_56_394_Open_Image onclick="this.style.display='none'; Codehighlighter1_56_394_Open_Text.style.display='none'; Codehighlighter1_56_394_Closed_Image.style.display='inline'; Codehighlighter1_56_394_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_56_394_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_56_394_Closed_Text.style.display='none'; Codehighlighter1_56_394_Open_Image.style.display='inline'; Codehighlighter1_56_394_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_56_394_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_56_394_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(e)<br><img id=Codehighlighter1_67_113_Open_Image onclick="this.style.display='none'; Codehighlighter1_67_113_Open_Text.style.display='none'; Codehighlighter1_67_113_Closed_Image.style.display='inline'; Codehighlighter1_67_113_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_67_113_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_67_113_Closed_Text.style.display='none'; Codehighlighter1_67_113_Open_Image.style.display='inline'; Codehighlighter1_67_113_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_67_113_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_67_113_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MOELOG_DETAIL_WARN(e.message().c_str());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Connection</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;p&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;mNextConnection;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;mNextConnection&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Connection(</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;再次进入监听状态</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mAcceptor.async_accept(mNextConnection</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">getSocket(),<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">ServerFramework::__onConnect,&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boost::asio::placeholders::error));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;处理当前链接</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;__addConnection(p);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;p</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">start();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>最后，展示一下这个类的所有成员变量吧：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;用于线程池异步处理的核心对象</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;boost::asio::io_service&nbsp;mIoService;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;网络链接的接收器，用于接收请求进入的链接</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;boost::asio::ip::tcp::acceptor&nbsp;mAcceptor;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;指向下一个将要被使用的链接对象</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Connection</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;mNextConnection;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;存储服务器链接对象的容器</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;ConnectionSet&nbsp;mConnections;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_225_265_Open_Image onclick="this.style.display='none'; Codehighlighter1_225_265_Open_Text.style.display='none'; Codehighlighter1_225_265_Closed_Image.style.display='inline'; Codehighlighter1_225_265_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_225_265_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_225_265_Closed_Text.style.display='none'; Codehighlighter1_225_265_Open_Image.style.display='inline'; Codehighlighter1_225_265_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_225_265_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_225_265_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">/&nbsp;为链接对象容器准备的strand，防止并行调用mConnections</span><span style="COLOR: #808080"></span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">boost::asio::io_service::strand&nbsp;mStrand_mConnections;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;为链接对象容器准备的同步锁，防止并行调用mConnections</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;boost::mutex&nbsp;mMutex4ConnSet;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;为控制台输出流准备的strand，防止并行调用std::cout</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;AsioService::strand&nbsp;mStrand_ConsoleIostream;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;工作线程的数量</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;uint32&nbsp;mWorkerCount;</span></div>
<br><br><br>但愿这篇随笔也能对正在研究asio的朋友们有所帮助吧。<br>
<img src ="http://www.cppblog.com/shanoa/aggbug/88606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-06-26 22:14 <a href="http://www.cppblog.com/shanoa/archive/2009/06/26/88606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost::bind绑定成员函数时，第一个参数传递对象的特殊情况</title><link>http://www.cppblog.com/shanoa/archive/2009/06/15/87746.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Mon, 15 Jun 2009 14:34:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/06/15/87746.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/87746.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/06/15/87746.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/87746.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/87746.html</trackback:ping><description><![CDATA[boost::bind(&amp;memberfunction, obj, _1, _2........)类似这样的用法，我们叫做成员函数绑定，boost库的文档中说的很清楚，第一个参数可以是value、pointer和reference，即传值、传地址和传引用都是可以的，所以在一般情况下，下面三种使用bind的形式都是成立的。<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;A<br><img id=Codehighlighter1_9_33_Open_Image onclick="this.style.display='none'; Codehighlighter1_9_33_Open_Text.style.display='none'; Codehighlighter1_9_33_Closed_Image.style.display='inline'; Codehighlighter1_9_33_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_9_33_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_9_33_Closed_Text.style.display='none'; Codehighlighter1_9_33_Open_Image.style.display='inline'; Codehighlighter1_9_33_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_9_33_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_9_33_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;func();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>A&nbsp;a;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>A</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;r&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">A::func,&nbsp;a);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a::func,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a::func,&nbsp;r);</span></div>
<br>由上面的代码可以看出，我们可以随便传任意一种类对象的形式，函数模板会自动寻找最为匹配的为我们实现。但是有两种情况是特殊的，即：<br>1、该对象不可进行拷贝构造函数。<br>2、该对象不可随意被析构。<br>发现这个问题是在我编写单件模式时的遇见的，当时发现我的单件对象在bind中被析构了一次，这很不寻常，为什么bind会调用第一个参数的析构呢？跟踪进了boost的源码才发现，原来所有的参数都会被拷贝一遍，然后析构一遍，这样一来，我们传递参数的时候就会有一些小麻烦了，首先必须保证参数能够被拷贝而不影响逻辑和数据一致性，其次，参数能够被析构而不影响逻辑和数据一致性。单件是全局性质的数据，所以绝对不可以析构，那么这种情况的话，我们只好传递单件对象的地址，而不能传递值或引用。<br><br>另：附上出错问题的代码如下<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;InputDevice<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;EventSource<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;,&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Singleton</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">InputDevice</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_73_85_Open_Image onclick="this.style.display='none'; Codehighlighter1_73_85_Open_Text.style.display='none'; Codehighlighter1_73_85_Closed_Image.style.display='inline'; Codehighlighter1_73_85_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_73_85_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_73_85_Closed_Text.style.display='none'; Codehighlighter1_73_85_Open_Image.style.display='inline'; Codehighlighter1_73_85_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_73_85_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_73_85_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TestUI<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Singleton</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">TestUI</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_130_338_Open_Image onclick="this.style.display='none'; Codehighlighter1_130_338_Open_Text.style.display='none'; Codehighlighter1_130_338_Closed_Image.style.display='inline'; Codehighlighter1_130_338_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_130_338_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_130_338_Closed_Text.style.display='none'; Codehighlighter1_130_338_Open_Image.style.display='inline'; Codehighlighter1_130_338_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_130_338_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_130_338_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img id=Codehighlighter1_150_188_Open_Image onclick="this.style.display='none'; Codehighlighter1_150_188_Open_Text.style.display='none'; Codehighlighter1_150_188_Closed_Image.style.display='inline'; Codehighlighter1_150_188_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_150_188_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_150_188_Closed_Text.style.display='none'; Codehighlighter1_150_188_Open_Image.style.display='inline'; Codehighlighter1_150_188_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">TestUI()</span><span id=Codehighlighter1_150_188_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_150_188_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">~TestUI</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_228_263_Open_Image onclick="this.style.display='none'; Codehighlighter1_228_263_Open_Text.style.display='none'; Codehighlighter1_228_263_Closed_Image.style.display='inline'; Codehighlighter1_228_263_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_228_263_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_228_263_Closed_Text.style.display='none'; Codehighlighter1_228_263_Open_Image.style.display='inline'; Codehighlighter1_228_263_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;processKeyboard(EventArgs</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;args)</span><span id=Codehighlighter1_228_263_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_228_263_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">键盘响应</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_301_336_Open_Image onclick="this.style.display='none'; Codehighlighter1_301_336_Open_Text.style.display='none'; Codehighlighter1_301_336_Closed_Image.style.display='inline'; Codehighlighter1_301_336_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_301_336_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_301_336_Closed_Text.style.display='none'; Codehighlighter1_301_336_Open_Image.style.display='inline'; Codehighlighter1_301_336_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;processMouse(EventArgs</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;args)</span><span id=Codehighlighter1_301_336_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_301_336_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">鼠标响应</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br><img id=Codehighlighter1_380_1763_Open_Image onclick="this.style.display='none'; Codehighlighter1_380_1763_Open_Text.style.display='none'; Codehighlighter1_380_1763_Closed_Image.style.display='inline'; Codehighlighter1_380_1763_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_380_1763_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_380_1763_Closed_Text.style.display='none'; Codehighlighter1_380_1763_Open_Image.style.display='inline'; Codehighlighter1_380_1763_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_380_1763_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_380_1763_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;FrameUpdaterManager;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;DelayEventSender;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;InputDevice;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;TestUI;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet.addEvent(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">KeyDown</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;Event());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet.addEvent(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">KeyUp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;Event());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet.addEvent(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseLDown</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;Event());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet.addEvent(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseLUp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;Event());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet.addEvent(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseRDown</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;Event());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet.addEvent(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseRUp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;Event());<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">TestUI&amp;&nbsp;ui&nbsp;=&nbsp;TestUI::getSingleton();&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;用此行便会出错</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;TestUI</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;ui&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;TestUI::getSingletonPtr();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;出错开始</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">KeyDown</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">TestUI::processKeyboard,&nbsp;ui,&nbsp;_1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">KeyUp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">TestUI::processKeyboard,&nbsp;ui,&nbsp;_1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseLDown</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">TestUI::processMouse,&nbsp;ui,&nbsp;_1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseLUp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">TestUI::processMouse,&nbsp;ui,&nbsp;_1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseRDown</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">TestUI::processMouse,&nbsp;ui,&nbsp;_1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;InputDevice::getSingleton().mEventSet[</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">MouseRUp</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;boost::bind(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">TestUI::processMouse,&nbsp;ui,&nbsp;_1);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;TestUI::getSingletonPtr();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;InputDevice::getSingletonPtr();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;DelayEventSender::getSingletonPtr();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;FrameUpdaterManager::getSingletonPtr();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<img src ="http://www.cppblog.com/shanoa/aggbug/87746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-06-15 22:34 <a href="http://www.cppblog.com/shanoa/archive/2009/06/15/87746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4cxx C++的日志库使用随记</title><link>http://www.cppblog.com/shanoa/archive/2009/06/10/87342.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Wed, 10 Jun 2009 09:03:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/06/10/87342.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/87342.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/06/10/87342.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/87342.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/87342.html</trackback:ping><description><![CDATA[log4cxx是一个不错的库，利用配置文件就可以很灵活的使用它。<br>说说具体用法，首先当然是在你的C++代码中写上Log的各种东西了<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">log4cxx</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">logger.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">log4cxx</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">logstring.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">log4cxx</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">propertyconfigurator.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br><img id=Codehighlighter1_139_587_Open_Image onclick="this.style.display='none'; Codehighlighter1_139_587_Open_Text.style.display='none'; Codehighlighter1_139_587_Closed_Image.style.display='inline'; Codehighlighter1_139_587_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_139_587_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_139_587_Closed_Text.style.display='none'; Codehighlighter1_139_587_Open_Image.style.display='inline'; Codehighlighter1_139_587_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_139_587_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_139_587_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;log4cxx;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;读取配置文件</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;PropertyConfigurator::configure(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">log4cxx.cfg</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;建立两个logger</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;LoggerPtr&nbsp;logger1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Logger::getLogger(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">TraceYourMama</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LoggerPtr&nbsp;logger2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Logger::getLogger(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Patch</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LOG4CXX_TRACE(logger1,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">跟踪</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LOG4CXX_WARN(logger1,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">警告</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LOG4CXX_DEBUG(logger1,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">调试</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LOG4CXX_ASSERT(logger1,&nbsp;</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">断言</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LOG4CXX_FATAL(logger1,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">致命</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LOG4CXX_TRACE(logger2,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">跟踪</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;LOG4CXX_ERROR(logger2,&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">错误</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>其实在实际应用中，每个类都可以搞一个logger，然后在配置文件中进行如下的设置：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#&nbsp;设置root&nbsp;logger为DEBUG级别<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#log4j.rootLogger</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">TRACE</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">ca<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.logger.TraceYourMama</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">ERROR</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">fa</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">ha<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.logger.Patch</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">Trace</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">ca<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#设置spirit为TRACE级别<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#log4j.spirit</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">DEBUG<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#log4j.additivity.spirit</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">false<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;%m&nbsp;-&nbsp;message<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;%n&nbsp;-&nbsp;回车<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;%d&nbsp;-&nbsp;时间<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;%.16c&nbsp;-&nbsp;Logger名称<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;%-5p&nbsp;-&nbsp;log级别<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;%t&nbsp;-&nbsp;thread_id<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#对Appender&nbsp;ca进行设置：<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#这是一个控制台类型的Appender<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#输出格式（layout）为PatternLayout<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.ca</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">org.apache.log4j.ConsoleAppender<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.ca.layout</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">org.apache.log4j.PatternLayout<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.ca.layout.ConversionPattern</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">%d&nbsp;%-5p&nbsp;%.16c&nbsp;-&nbsp;%m%n<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#对Appender&nbsp;fa进行设置：<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;这是一个文件类型的Appender，<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;其输出文件（File）为./debug.log，<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;输出方式（Append）为覆盖方式，<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#&nbsp;输出格式（layout）为PatternLayout<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.fa</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">org.apache.log4j.FileAppender<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.fa.File</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">./debug.log<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.fa.Append</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">true<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.fa.layout</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">org.apache.log4j.PatternLayout<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#log4j.appender.fa.layout.ConversionPattern</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">%d&nbsp;</span><span style="FONT-WEIGHT: bold; COLOR: #800000">[</span><span style="COLOR: #800000">%t</span><span style="FONT-WEIGHT: bold; COLOR: #800000">]</span><span style="COLOR: #000000">&nbsp;%-5p&nbsp;%.16c&nbsp;%x&nbsp;-&nbsp;%m%n<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>log4j.appender.fa.layout.ConversionPattern</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">%d&nbsp;%-5p&nbsp;%.16c&nbsp;-&nbsp;%m%n<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br><br>
<img src ="http://www.cppblog.com/shanoa/aggbug/87342.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-06-10 17:03 <a href="http://www.cppblog.com/shanoa/archive/2009/06/10/87342.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost statechart</title><link>http://www.cppblog.com/shanoa/archive/2009/05/30/86143.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Sat, 30 May 2009 00:34:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/05/30/86143.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/86143.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/05/30/86143.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/86143.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/86143.html</trackback:ping><description><![CDATA[<p>接触了boost的状态机，发现不是想象中的那么好用，在一些地方还得用上mpl库里的东西，由于对模板元编程不是很熟练，搞了好些天才算弄明白这该死的mpl::list的原理和用法。<br>boost的状态机是属于静态链接的状态机，也就是说，它的图结构是编译期间就确定了的，在运行时不可以动态配置。所以，它的用途是有一定局限性的，但在一般情况下，它不仅很通用，而且在你会用并熟练地情况下，还会很好用，用起来很舒服，逻辑也很合理。下面就是一段代码，当然也是借鉴了别人的东西，自己修改了一下，在MainState中添加了一个Transition做了测试，因为此前我还不知道一个状态如何包含多个Transition，呵呵，原来是用mpl::list来做。至于这个状态机的入门教程，网上随处可见的三部曲：《boost 状态机入门教程》说得很清楚。<br></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"><span style="COLOR: #008080">&nbsp;&nbsp;1</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;2</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ctime</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;3</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;4</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">boost</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">statechart</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">transition.hpp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;5</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">boost</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">statechart</span><span style="COLOR: #000000">/</span><span style="COLOR: #0000ff">event</span><span style="COLOR: #000000">.hpp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;6</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">boost</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">statechart</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">state_machine.hpp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;7</span>&nbsp;<span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">boost</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">statechart</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">simple_state.hpp</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;8</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;&nbsp;9</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000">&nbsp;sc&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;boost::statechart;<br></span><span style="COLOR: #008080">&nbsp;10</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;11</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;12</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;13</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;EvtStartStop&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::</span><span style="COLOR: #0000ff">event</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtStartStop</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">{};<br></span><span style="COLOR: #008080">&nbsp;14</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;EvtReset&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::</span><span style="COLOR: #0000ff">event</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtReset</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">{};<br></span><span style="COLOR: #008080">&nbsp;15</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;EvtGo&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::</span><span style="COLOR: #0000ff">event</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtGo</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">{};<br></span><span style="COLOR: #008080">&nbsp;16</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;17</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;18</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MainState;<br></span><span style="COLOR: #008080">&nbsp;19</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;StopState;<br></span><span style="COLOR: #008080">&nbsp;20</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;RunState;<br></span><span style="COLOR: #008080">&nbsp;21</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TwoState;<br></span><span style="COLOR: #008080">&nbsp;22</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;23</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Machine&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::state_machine</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Machine,&nbsp;MainState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;24</span>&nbsp;<span style="COLOR: #000000">{};<br></span><span style="COLOR: #008080">&nbsp;25</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;26</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;27</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;28</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;29</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;30</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;31</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MainState&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::simple_state</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">MainState,&nbsp;Machine,&nbsp;StopState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;32</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;33</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;34</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;sc::transition</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtReset,&nbsp;MainState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;reactReset;<br></span><span style="COLOR: #008080">&nbsp;35</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;sc::transition</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtGo,&nbsp;TwoState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;reactGo;<br></span><span style="COLOR: #008080">&nbsp;36</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;boost::mpl::list</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">reactReset,&nbsp;reactGo</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;reactions;<br></span><span style="COLOR: #008080">&nbsp;37</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;38</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;MainState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;39</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">进入MainState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;40</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mTime&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;41</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;42</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;43</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">MainState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;44</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">退出MainState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;45</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;46</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;47</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;mTime;<br></span><span style="COLOR: #008080">&nbsp;48</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">&nbsp;49</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;50</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;51</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;该状态属于无用状态，用于测试mpl::list的多transition用法</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;52</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TwoState&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::simple_state</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">TwoState,&nbsp;Machine</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;53</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;54</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;55</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;sc::transition</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtGo,&nbsp;MainState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;reactions;<br></span><span style="COLOR: #008080">&nbsp;56</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;57</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;TwoState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;58</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">进入TwoState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;59</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;60</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;61</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">TwoState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;62</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">退出TwoState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;63</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;64</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">&nbsp;65</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;66</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;67</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;StopState&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::simple_state</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">StopState,&nbsp;MainState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;68</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;69</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;70</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;sc::transition</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtStartStop,&nbsp;RunState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;reactions;<br></span><span style="COLOR: #008080">&nbsp;71</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;StopState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;72</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">进入StopState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;73</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;74</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;75</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">StopState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;76</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">退出StopState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;77</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;78</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">&nbsp;79</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;80</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;RunState&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;sc::simple_state</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">RunState,&nbsp;MainState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;81</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;82</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;83</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;sc::transition</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">EvtStartStop,&nbsp;StopState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;reactions;<br></span><span style="COLOR: #008080">&nbsp;84</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;RunState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;85</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">进入RunState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;86</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mStartTime&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;87</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;88</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;89</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000">RunState(</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">){<br></span><span style="COLOR: #008080">&nbsp;90</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">退出RunState</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">&nbsp;91</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">MainState</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">().mTime&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;std::difftime(std::time(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">),&nbsp;mStartTime);<br></span><span style="COLOR: #008080">&nbsp;92</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">&nbsp;93</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;94</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::time_t&nbsp;mStartTime;<br></span><span style="COLOR: #008080">&nbsp;95</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">&nbsp;96</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;97</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;98</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br></span><span style="COLOR: #008080">&nbsp;99</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">100</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Machine&nbsp;mc;<br></span><span style="COLOR: #008080">101</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mc.initiate();<br></span><span style="COLOR: #008080">102</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">103</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mc.process_event(EvtStartStop());<br></span><span style="COLOR: #008080">104</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mc.process_event(EvtStartStop());<br></span><span style="COLOR: #008080">105</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mc.process_event(EvtReset());<br></span><span style="COLOR: #008080">106</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mc.process_event(EvtGo());<br></span><span style="COLOR: #008080">107</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;mc.process_event(EvtGo());<br></span><span style="COLOR: #008080">108</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">109</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><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">110</span>&nbsp;<span style="COLOR: #000000">}</span></div>
<img src ="http://www.cppblog.com/shanoa/aggbug/86143.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-05-30 08:34 <a href="http://www.cppblog.com/shanoa/archive/2009/05/30/86143.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模版特例化</title><link>http://www.cppblog.com/shanoa/archive/2009/05/25/85683.html</link><dc:creator>酿妹汁</dc:creator><author>酿妹汁</author><pubDate>Mon, 25 May 2009 03:14:00 GMT</pubDate><guid>http://www.cppblog.com/shanoa/archive/2009/05/25/85683.html</guid><wfw:comment>http://www.cppblog.com/shanoa/comments/85683.html</wfw:comment><comments>http://www.cppblog.com/shanoa/archive/2009/05/25/85683.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/shanoa/comments/commentRss/85683.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shanoa/services/trackbacks/85683.html</trackback:ping><description><![CDATA[<p>写模版多了的人，必然会遇到这样那样的问题，模版特例化就是解决了一个经常碰见的问题：如果我们需要根据某些特殊的模版参数类型来重新实现一下算法的话，该怎么办呢？说的多了那也没什么用，我们就写一个会做除法的类吧。这个类在做整数除法的时候会同时求出余数，而在算其他类型时是不求的。代码如下：<br><br></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"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">#include&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">iostream</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;Ty</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Division<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img id=Codehighlighter1_59_254_Open_Image onclick="this.style.display='none'; Codehighlighter1_59_254_Open_Text.style.display='none'; Codehighlighter1_59_254_Closed_Image.style.display='inline'; Codehighlighter1_59_254_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_59_254_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_59_254_Closed_Text.style.display='none'; Codehighlighter1_59_254_Open_Image.style.display='inline'; Codehighlighter1_59_254_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_59_254_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_59_254_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Division(Ty&nbsp;dividend,&nbsp;Ty&nbsp;divisor)<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img id=Codehighlighter1_145_146_Open_Image onclick="this.style.display='none'; Codehighlighter1_145_146_Open_Text.style.display='none'; Codehighlighter1_145_146_Closed_Image.style.display='inline'; Codehighlighter1_145_146_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_145_146_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_145_146_Closed_Text.style.display='none'; Codehighlighter1_145_146_Open_Image.style.display='inline'; Codehighlighter1_145_146_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mDividend(dividend),&nbsp;mDivisor(divisor)</span><span id=Codehighlighter1_145_146_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_145_146_Open_Text><span style="COLOR: #000000">{}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;show()<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img id=Codehighlighter1_170_226_Open_Image onclick="this.style.display='none'; Codehighlighter1_170_226_Open_Text.style.display='none'; Codehighlighter1_170_226_Closed_Image.style.display='inline'; Codehighlighter1_170_226_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_170_226_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_170_226_Closed_Text.style.display='none'; Codehighlighter1_170_226_Open_Image.style.display='inline'; Codehighlighter1_170_226_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_170_226_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_170_226_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">结果&nbsp;=&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">mDividend</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">mDivisor</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Ty&nbsp;mDividend,&nbsp;mDivisor;<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>inline&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Division</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::show()<br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img id=Codehighlighter1_303_409_Open_Image onclick="this.style.display='none'; Codehighlighter1_303_409_Open_Text.style.display='none'; Codehighlighter1_303_409_Closed_Image.style.display='inline'; Codehighlighter1_303_409_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_303_409_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_303_409_Closed_Text.style.display='none'; Codehighlighter1_303_409_Open_Image.style.display='inline'; Codehighlighter1_303_409_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_303_409_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_303_409_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">结果&nbsp;=&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">mDividend</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">mDivisor</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">余数&nbsp;=&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">mDividend</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">mDivisor</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">28</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">29</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;_tmain(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;argv[])<br></span><span style="COLOR: #008080">30</span><span style="COLOR: #000000"><img id=Codehighlighter1_452_548_Open_Image onclick="this.style.display='none'; Codehighlighter1_452_548_Open_Text.style.display='none'; Codehighlighter1_452_548_Closed_Image.style.display='inline'; Codehighlighter1_452_548_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_452_548_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_452_548_Closed_Text.style.display='none'; Codehighlighter1_452_548_Open_Image.style.display='inline'; Codehighlighter1_452_548_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_452_548_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_452_548_Open_Text><span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">31</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Division</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;a(</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">32</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;a.show();<br></span><span style="COLOR: #008080">33</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br></span><span style="COLOR: #008080">34</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Division</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;b(</span><span style="COLOR: #000000">20.0f</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">11.0f</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">35</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;b.show();<br></span><span style="COLOR: #008080">36</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">37</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<br>以上这种方式就叫做局部特化，关于全部特化和局部特化、全特化和偏特化，我认为他们之间的关系很紧密，界限也很模糊，硬要分类的话，以上面的Division类为例，就看下面的代码对全部特化和局部特化的区别吧：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">*<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #008000">@remark<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #008000">&nbsp;Division的全部特化<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Division</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Division(Ty&nbsp;dividend,&nbsp;Ty&nbsp;divisor)<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:mDividend(dividend),&nbsp;mDivisor(divisor){}<br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;show()<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">结果&nbsp;=&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">mDividend</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">mDivisor</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">余数&nbsp;=&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">mDividend</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">mDivisor</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;Ty&nbsp;mDividend,&nbsp;mDivisor;<br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">*<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #008000">@remark<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #008000">Division的局部特化<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000">inline&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;Division</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::show()<br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">结果&nbsp;=&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">mDividend</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">mDivisor</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;std::cout</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">余数&nbsp;=&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">mDividend</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">mDivisor</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">std::endl;<br></span><span style="COLOR: #008080">30</span>&nbsp;<span style="COLOR: #000000">}</span></div>
上面的代码只是说明了全部特化和局部特化，并没有说明什么事全特化和偏特化。其实，对于只有一个参数的模版类型来说，并没有什么全特化和偏特化的区别，但如果是一个以上的模板参数，那就是由区别的了，如下：<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-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span>&nbsp;<span style="COLOR: #008000">/*</span><span style="COLOR: #008000">*<br></span><span style="COLOR: #008080">&nbsp;2</span>&nbsp;<span style="COLOR: #008000">@remark<br></span><span style="COLOR: #008080">&nbsp;3</span>&nbsp;<span style="COLOR: #008000">原始模板类<br></span><span style="COLOR: #008080">&nbsp;4</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;5</span>&nbsp;<span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;Ty,&nbsp;typename&nbsp;TyEx</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;6</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ObjectData<br></span><span style="COLOR: #008080">&nbsp;7</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">&nbsp;8</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;9</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">10</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">11</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">*<br></span><span style="COLOR: #008080">12</span>&nbsp;<span style="COLOR: #008000">@remark<br></span><span style="COLOR: #008080">13</span>&nbsp;<span style="COLOR: #008000">Object的全特化<br></span><span style="COLOR: #008080">14</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span>&nbsp;<span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">16</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ObjectData</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">18</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">19</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">};<br></span><span style="COLOR: #008080">20</span>&nbsp;<span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">*<br></span><span style="COLOR: #008080">22</span>&nbsp;<span style="COLOR: #008000">@remark<br></span><span style="COLOR: #008080">23</span>&nbsp;<span style="COLOR: #008000">Object的偏特化，只特化第一个参数<br></span><span style="COLOR: #008080">24</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">25</span>&nbsp;<span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;TyEx</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">26</span>&nbsp;<span style="COLOR: #000000"></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ObjectData</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">,&nbsp;TyEx</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">27</span>&nbsp;<span style="COLOR: #000000">{<br></span><span style="COLOR: #008080">28</span>&nbsp;<span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/dot.gif"></span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">29</span>&nbsp;<span style="COLOR: #008000"></span><span style="COLOR: #000000">};</span></div>
<br>以上仅为个人观点，错误之处请指正。<br>
<img src ="http://www.cppblog.com/shanoa/aggbug/85683.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shanoa/" target="_blank">酿妹汁</a> 2009-05-25 11:14 <a href="http://www.cppblog.com/shanoa/archive/2009/05/25/85683.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>