﻿<?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++博客-金庆的专栏</title><link>http://www.cppblog.com/jinq0123/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 22 Mar 2010 02:40:05 GMT</lastBuildDate><pubDate>Mon, 22 Mar 2010 02:40:05 GMT</pubDate><ttl>60</ttl><item><title>不喜欢KOK3中人物无阻挡的设定</title><link>http://www.cppblog.com/jinq0123/archive/2010/03/19/110098.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 19 Mar 2010 05:43:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/03/19/110098.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/110098.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/03/19/110098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/110098.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/110098.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 3D网游万王之王3（KOK3）中人物之间是没有阻挡的，<br>两个人可以相互穿透，不会有一个人挡住另一个人的现象。<br>玩家和怪物之间也是没有阻挡的，一个人可以在一大群拥挤的怪物中间穿来穿去。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/03/19/110098.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/110098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-03-19 13:43 <a href="http://www.cppblog.com/jinq0123/archive/2010/03/19/110098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>圈复杂度和代码覆盖率</title><link>http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 09 Mar 2010 01:42:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/109242.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/109242.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/109242.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 100%代码覆盖率的单元测试并不代表是足够的测试，下面是一个例子：&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/109242.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-03-09 09:42 <a href="http://www.cppblog.com/jinq0123/archive/2010/03/09/109242.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大型多人游戏中间件</title><link>http://www.cppblog.com/jinq0123/archive/2010/02/25/108434.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 25 Feb 2010 08:24:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/02/25/108434.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/108434.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/02/25/108434.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/108434.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/108434.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Massively Multiplayer Middleware<br>大型多人游戏中间件<br>MICHI HENNING, ZeroC<br>Building scaleable middleware for ultra-massive online games teaches a lesson we all can use: Big project, simple design.<br>为超大型在线游戏构建可扩展的中间件给我们所有人的教训：宏大的项目，简单的设计。 &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/02/25/108434.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/108434.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-02-25 16:24 <a href="http://www.cppblog.com/jinq0123/archive/2010/02/25/108434.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>需要判断指针为空吗</title><link>http://www.cppblog.com/jinq0123/archive/2010/02/11/107690.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 11 Feb 2010 01:48:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/02/11/107690.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/107690.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/02/11/107690.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/107690.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/107690.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 前几天，KOK3客户端因为我的资源配置错误而崩溃了。<br>调试器带我到了出错的代码行，是一个空指针解引用。<br>代码大致如下：<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/02/11/107690.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/107690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-02-11 09:48 <a href="http://www.cppblog.com/jinq0123/archive/2010/02/11/107690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网游云计算？</title><link>http://www.cppblog.com/jinq0123/archive/2010/02/08/107504.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 08 Feb 2010 10:13:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/02/08/107504.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/107504.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/02/08/107504.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/107504.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/107504.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 《神仙OL》在最新版本中引入了基于云计算的同步技术&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/02/08/107504.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/107504.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-02-08 18:13 <a href="http://www.cppblog.com/jinq0123/archive/2010/02/08/107504.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网游数据的推和拉</title><link>http://www.cppblog.com/jinq0123/archive/2010/02/01/106927.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 01 Feb 2010 02:11:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/02/01/106927.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/106927.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/02/01/106927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/106927.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/106927.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 应该允许客户端自行决定从服务器获取数据的方式。<br>1. 拉方式：请求时才发送。<br>2. 推方式：服务器主动发送。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/02/01/106927.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/106927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-02-01 10:11 <a href="http://www.cppblog.com/jinq0123/archive/2010/02/01/106927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网游电影</title><link>http://www.cppblog.com/jinq0123/archive/2010/01/26/106447.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 26 Jan 2010 01:57:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/01/26/106447.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/106447.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/01/26/106447.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/106447.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/106447.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 网游小说，网游电影，网游三位一体，相互促进，共同演绎一个虚拟的世界。<br><br>巨人网络不排除在影视方面进行尝试和投资。（http://www.bianews.com/viewnews-153862.html ）&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/01/26/106447.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/106447.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-01-26 09:57 <a href="http://www.cppblog.com/jinq0123/archive/2010/01/26/106447.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用agent统一玩家与NPC</title><link>http://www.cppblog.com/jinq0123/archive/2010/01/22/106208.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 22 Jan 2010 02:19:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/01/22/106208.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/106208.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/01/22/106208.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/106208.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/106208.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有了agent, 角色与NPC就统一了。<br>agent中可以配置各种AI，以帮助角色和NPC有各种行为。<br>NPC AI只是agent的一部份。NPC就是没有人控制的agent.&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/01/22/106208.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/106208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-01-22 10:19 <a href="http://www.cppblog.com/jinq0123/archive/2010/01/22/106208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何保持软件开发团队的稳定性</title><link>http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 20 Jan 2010 05:18:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/106061.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/106061.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/106061.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 保持团队的稳定性说来容易，其实对于每一个优秀的研发经理和公司CEO都非常具有挑战性，尤其是员工很多时候并不能意识到这一点和理解领导层的压力。就好比单身汉不能理解父亲的心情一样。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/106061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-01-20 13:18 <a href="http://www.cppblog.com/jinq0123/archive/2010/01/20/106061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>随机数生成器应该如何单元测试？</title><link>http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 09 Jan 2010 04:24:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/105236.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/105236.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/105236.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有个随机数生成函数，按以下分布随机生成1个1-100的整数：90%概率为1-50，10%概率为51-100.<br>单元测试应该如何进行呢？<br>生成10000个数然后计算分布比例应该可以，只要在90%上下就算通过。<br>但是仍有极小可能产生测试失败的可能。<br>如何做一个具有确定性结论的测试用例？ &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/105236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-01-09 12:24 <a href="http://www.cppblog.com/jinq0123/archive/2010/01/09/105236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++类定义中应该允许设置默认值</title><link>http://www.cppblog.com/jinq0123/archive/2009/12/12/103035.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 12 Dec 2009 03:20:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/12/12/103035.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/103035.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/12/12/103035.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/103035.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/103035.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C++类定义中应该允许设置默认值目前C++的类成员初始化方式是成员初始化列表，在构造函数原型之后，以冒号分隔：A::A() : _n(0), _m(0) {     ... } 成员初始化列表这种方式很容易忘记或遗漏某个成员的初始化。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/12/12/103035.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/103035.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-12-12 11:20 <a href="http://www.cppblog.com/jinq0123/archive/2009/12/12/103035.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(Python编程)目录工具</title><link>http://www.cppblog.com/jinq0123/archive/2009/12/05/102599.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 05 Dec 2009 06:36:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/12/05/102599.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/102599.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/12/05/102599.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/102599.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/102599.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Programming Python, 3rd Edition 翻译<br><br>One of the more common tasks in the shell utilities domain is applying an operation to a set of files in a directorya "folder" in Windows-speak. By running a script on a batch of files, we can automate (that is, script) tasks we might have to otherwise run repeatedly by hand.<br><br>在shell应用领域，更常见的任务是，操作目录中的一组文件，按Windows的说法是“文件夹”。通过对一批文件运行脚本，我们可以将任务自动化（即脚本化），否则我们就必须以手工方式重复运行脚本。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/12/05/102599.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/102599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-12-05 14:36 <a href="http://www.cppblog.com/jinq0123/archive/2009/12/05/102599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>你愿意别人更改你的代码吗?</title><link>http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 21 Nov 2009 04:55:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/101550.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/101550.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/101550.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 看到怪盗KID的文章<br>( http://hi.baidu.com/kidcdf/blog/item/2cefd85c9d13f449fbf2c09f.html )<br>最后一句: 没有一个人喜欢看着自己辛辛苦苦做的东西被反复删掉重写.<br><br>个人觉得别人更改自己写的代码是我乐意接受的. 不知大家有什么想法?<br><br>你愿意别人更改你的代码吗?<br>A) 代码一旦提交, 就是大家公有的代码, 无所谓谁改谁的代码.<br>B) 很乐意有人愿意更改自己的代码.<br>C) 绝不允许别人更改自己的代码.<br>D) 看到自己的代码被人改了,感到很受打击.<br><br>还有其他别的感受吗?&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/101550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-11-21 12:55 <a href="http://www.cppblog.com/jinq0123/archive/2009/11/21/101550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网关按区域聚集玩家</title><link>http://www.cppblog.com/jinq0123/archive/2009/11/06/100277.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 06 Nov 2009 02:43:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/11/06/100277.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/100277.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/11/06/100277.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/100277.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/100277.html</trackback:ping><description><![CDATA[网关按区域聚集玩家<br><br>（转载请注明来源于金庆的专栏）<br><br>目前网游系统中的网关只发挥了隔离内外网和转发的功能, 至少征途和KOK3是这样.<br>按照尹红春的设计构想,网关还有个区域聚集功能. <br><br>区域聚集是这样的意思: 场景中的许多事件都是区域内广播的, <br>如角色或NPC的移动, 攻击, 状态变化, 场景服务器不必直接向该区域内的所有人广播,<br>而是只需向网关广播, 然后由各网关向该区域内的人广播.<br><br>因为目前场景服务器的负载并不重, 所以并没有实现网关的区域聚集.<br><br>在KOK3中可能有必要实现网关的区域聚集. <br>因为KOK3中玩家之间没有阻挡, 是可以相互重叠和穿越的.<br>无阻挡设定是为了增大区域内的玩家密度, 让界域战争之类的大型群体活动更爽.<br>(个人认为这种设定有点怪异, 感觉自己象个鬼魂, 整个世界也是虚无的.)<br>KOK3场景区域内聚集上万玩家是可能的, 所以网关的区域聚集功能也是必要的.<br>玩家的聚集程度越大, 网关区域聚集效果就越明显.<br><br>目前网关选择是按负载平衡分散的. 一个区域内的玩家应该是平均分散在各个网关.<br>这种方案是否可以改为按场景选择网关? <br>一个场景对应一个网关, 这样就不必向所有网关广播了, 只需向对应的网关单独发送.<br>玩家切换场景同时切换网关(目前客户端与网关是保持连接不变的). <br><br>客户端与网关保持连接是否必要? <br>帐号登录验证之后, 角色连接服务器是不需要再次输密码的.<br>连接占用的时间很短, 即使是无缝地图切换, 也不会造成游戏停顿.<br><br>如果网关数量增加到成百上千, 场景向所有网关广播也比较浪费,<br>可改为向两三个网关单独发送. <br>对于仅有一两个玩家的区域, 更是没必要进行网关广播.<br><br>网关可改为动态增长的, 区域内玩家过多就自动分裂成多个网关.<br>并且可以助此实现负载均衡.<br><br>网关切换可以不立即断开连接, 保持一段时间后再断, 防止来回频繁切换网关.<br>或者网关对应的场景是重叠的, 不会造成来回频繁切换网关.<br>因为网关上的用户之间无需处理交易之类的交互, 所以这种重叠是简单的, 可行的.<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/100277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-11-06 10:43 <a href="http://www.cppblog.com/jinq0123/archive/2009/11/06/100277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何删list靠近尾部的元素</title><link>http://www.cppblog.com/jinq0123/archive/2009/11/03/100054.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 03 Nov 2009 06:05:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/11/03/100054.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/100054.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/11/03/100054.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/100054.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/100054.html</trackback:ping><description><![CDATA[<p>摘自: <a href="http://www.cadcaecam.com/forum/thread-10455-1-1.html" class="external free" title="http://www.cadcaecam.com/forum/thread-10455-1-1.html" rel="nofollow">http://www.cadcaecam.com/forum/thread-10455-1-1.html</a>
</p>
<p>已知待删除元素靠近list的尾部, 是否可以从尾部搜索并删除呢?
</p>
<pre><span style="color: #760000; font-family: courier new;">   for (MYLIST::reverse_iterator i = mylist.rbegin(); i&nbsp;!= mylist.rend(); ++i)</span><br style="color: #760000; font-family: courier new;"><span style="color: #760000; font-family: courier new;">   {</span><br style="color: #760000; font-family: courier new;"><span style="color: #760000; font-family: courier new;">       if (THE_VALUE == *i)</span><br style="color: #760000; font-family: courier new;"><span style="color: #760000; font-family: courier new;">           mylist.erase(i);</span><br style="color: #760000; font-family: courier new;"><span style="color: #760000; font-family: courier new;">   }</span><br></pre>
<p>因为erase()只不能以反向迭代器为参数, 上述代码行不通.
</p>
<p><br>
应该是:
</p>
<pre><span style="color: #760000; font-family: courier new;">    if (THE_VALUE == *i)</span><br style="color: #760000; font-family: courier new;"><span style="color: #760000; font-family: courier new;">           mylist.erase((++i).base());</span><br></pre>
（转载请注明来源于金庆的专栏）<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/100054.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-11-03 14:05 <a href="http://www.cppblog.com/jinq0123/archive/2009/11/03/100054.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用惯性和加速度进行网游位置同步</title><link>http://www.cppblog.com/jinq0123/archive/2009/10/30/99835.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 30 Oct 2009 07:54:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/10/30/99835.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/99835.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/10/30/99835.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/99835.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/99835.html</trackback:ping><description><![CDATA[利用惯性和加速度进行网游位置同步<br><br>带宽限制下的视觉实体属性传播<br>(Propagation of Visual Entity Properties Under Bandwidth Constraints)<br>(http://blog.csdn.net/lfhfut/archive/2008/03/02/2138512.aspx)<br>一文中使用滞后补偿时间(LCT, Lag Compensation Time)来平滑客户端的显示.<br><br>在此方法下, 客户端主角显示在未来位置, 超前于服务器时间, <br>而同伴显示过去的位置, 滞后于服务器时间.<br>所以两个人一齐跑时, 总是会发现同伴落后于自己.<br><br>为了减弱同伴落后问题, LCT应该用于远方物体的位置同步, 越远LCT可以越大.<br>就像我们观察星星, 我们看到是其实是几万年前星星的样子, 因为星星距离我们有几万光年.<br>对于周围近距离的物体, LCT应该尽量小, 接近0.<br><br>所以上文并没有解决客户端的平滑问题.<br><br>文中所述的导航预测算法(DR, Dead Reckoning)并不应该放弃. <br>导航预测算法的原理是推算出未来的位置，LCT是将过去的位置作为现在位置来处理.<br>对于邻近物体, 应该显示未来的位置.<br>因为出于操作感的考虑, 主角的位置是超前于服务器的, 不可能等服务器确认后再移动.<br>所以周围同伴的位置也应该是超前的, 这样才不会有同伴总是落后于自己的现象.<br><br>导航预测算法不适用的主要原因是, 网游人物的移动是高度随机的, 状态更新太频繁.<br>这其实不是问题, 因为有预测肯定比没有预测要好. <br>在预测范围内, 就不必发位置更新.<br>最差情况下, 每个预测结果都是错误的, 必须修正为实际的位置, <br>这就退化成为没有预测的简单的位置更新方法.<br><br>但是如果网络延时50ms, 这50ms的预测是必须的. <br>因为客户端表现的是超前服务器50ms前的景象.<br><br>这就存在同伴掉下悬崖的现象, 因为同伴在悬崖边上的停止的消息要在50ms后才到.<br>这种问题在预测法中是无法解决的, 除非添加行为预测.<br><br>但是可以添加一个加速度来减少这种预测错误.<br>导航预测算法适用于飞机飞行模拟这类具有很大惯性的移动.<br>网游中的移动问题根源就是惯性不足, 有了惯性, 角色将无法任意更改移动状态,<br>从而大大减少预测错误.<br><br>人物在悬崖边上停止的动作必须有个减速的过程, 只要在50ms之前减速, <br>就会正确计算出停止点, 避免了坠崖. 开始移动时也是有个加速过程.<br><br>并且, 客户端主角的惯性可以大于服务器端, 而周围物体的惯性可以小于服务器端.<br>产生的效果是, 主角的动作变迟钝, 减少超前时间.<br>而周围物体稍稍灵活, 增加了超前时间.<br><br>或许我们所处的世界也是虚拟的, 创世者为了位置同步而给我们这个世界加上了惯性和加速度的规则.
<br><br>（转载请注明来源于金庆的专栏）
<br><br><br><img src ="http://www.cppblog.com/jinq0123/aggbug/99835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-10-30 15:54 <a href="http://www.cppblog.com/jinq0123/archive/2009/10/30/99835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++引用优于指针</title><link>http://www.cppblog.com/jinq0123/archive/2009/10/26/99454.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 26 Oct 2009 01:34:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/10/26/99454.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/99454.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/10/26/99454.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/99454.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/99454.html</trackback:ping><description><![CDATA[C++引用优于指针<br><br>（转载请注明来源于金庆的专栏）<br><br>在KOK3服务器的崩溃错误中, 十有八九是由空指针引起的.<br><br>在C语言中, 空指针确实是错误的一大来源, 到处是空指针判断, 可还是会有漏网的.<br><br>在C++中, 空指针错误可以大大减少, 方法就是尽量使用C++的引用代替指针.<br><br><span style="color: #6a0000; font-family: courier new;">void foo(A* pA)</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">{</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">&nbsp;&nbsp; &nbsp;BOOST_ASSERT(pA);</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">&nbsp;&nbsp; &nbsp;</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">&nbsp;&nbsp;&nbsp; // act on pA...</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">}</span><br><br>应该改为<br><br><span style="color: #6a0000; font-family: courier new;">void foo(A&amp; rA)</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">{</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">&nbsp;&nbsp;&nbsp; // act on rA...</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">}</span><br><br>如果输入参数为const, 那更是无疑的应该使用引用作为参数.<br><br>除了参数可以转成引用, 临时变量也尽量使用引用. 例如:<br><br><span style="color: #6a0000; font-family: courier new;">A* pA = getA();</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">if (pA)</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">{</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">&nbsp;&nbsp;&nbsp; // act on pA...</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">}</span><br style="color: #6a0000; font-family: courier new;"><br>可以改为<br><br><span style="color: #6a0000; font-family: courier new;">A* pA = getA();</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">if (pA)</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">{</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">&nbsp;&nbsp;&nbsp; A&amp; rA = *pA;</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">&nbsp;&nbsp;&nbsp; // act on rA...</span><br style="color: #6a0000; font-family: courier new;"><span style="color: #6a0000; font-family: courier new;">}</span><br><br>如果getA()不会返回NULL, 就将getA()改为返回引用, 而不是指针.<br>&nbsp;<br><img src ="http://www.cppblog.com/jinq0123/aggbug/99454.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-10-26 09:34 <a href="http://www.cppblog.com/jinq0123/archive/2009/10/26/99454.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是开发人员有意义的方向</title><link>http://www.cppblog.com/jinq0123/archive/2009/10/24/99359.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 24 Oct 2009 08:59:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/10/24/99359.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/99359.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/10/24/99359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/99359.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/99359.html</trackback:ping><description><![CDATA[在这个社会里，你只有做出令人尊敬的产品，才能赢得认可。在技术行业里，学识，名望，人脉，金钱带来的价值都是可估量的，不可估量的是对行业留下的创新设计，让你无愧于工程师这个称号。
<br><br>--摘自<span style="font-weight: bold;">"</span><a href="http://timyang.net/misc/tech-life/" rel="bookmark" title="Permanent Link to 谈技术人员研究方向">谈技术人员研究方向"</a><img src ="http://www.cppblog.com/jinq0123/aggbug/99359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-10-24 16:59 <a href="http://www.cppblog.com/jinq0123/archive/2009/10/24/99359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>广播游戏</title><link>http://www.cppblog.com/jinq0123/archive/2009/10/14/98568.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 14 Oct 2009 05:17:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/10/14/98568.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/98568.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/10/14/98568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/98568.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/98568.html</trackback:ping><description><![CDATA[摘自: 传说中的战网2.0 超强功能集锦及猜想 <br>http://hi.baidu.com/%CF%C4%D6%E7%BE%AA%D5%DD/blog/item/85075cf44c587269ddc474d5.<br>html<br><br>广播游戏<br><br>　　两个（或者多个）玩家打算进行比赛，同时连接到一个广播服务器上，服务器记录下他<br>们比赛中所有的指令，然后传送给想看这场比赛的人。数据的传送不可以影响到比赛的玩家<br>，观众在游戏中就可以看到该比赛的直播。<br><br>　　为了防止观众帮助选手作弊，可以将观众的视频延迟几秒钟。该系统也可以几个小时再<br>播放，或者是存为replay以后播放，也可以为你的比赛找几个解说员，和当下电视上播放的<br>体育节目一样，你从你的屏幕就可以直接看到解说员做的解说注释。<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/98568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-10-14 13:17 <a href="http://www.cppblog.com/jinq0123/archive/2009/10/14/98568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网游防刷指令攻击的设计</title><link>http://www.cppblog.com/jinq0123/archive/2009/09/22/96961.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 22 Sep 2009 09:43:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/09/22/96961.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/96961.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/09/22/96961.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/96961.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/96961.html</trackback:ping><description><![CDATA[网游防刷指令攻击的设计<br><br>网游外挂可以重复发送某些指令,造成服务器CPU占用或带宽占用,这类攻击称为刷指令.<br><br>最简单的如聊天广播. 不需要特殊的外挂, 只需在客户端全域或区域喊话, <br>该聊天信息就会广播到所有客户端, 占用许多带宽. <br>一般需要通过限制聊天的间隔时间, 或者收费来防止刷屏聊天.<br><br>其他指令也需要这种防刷措施. <br><br>防刷指令应该做成一个通用机制, 控制所有指令, 而不是仅仅对个别指令处理.<br>默认情况下, 所有客户端发往服务器的指令都要受到限制.<br><br>指令限制功能应该放在网关, 不会影响游戏服务器. <br>但也要求算法尽量简单, 能够快速处理.<br><br>最简单的限制方法是限制间隔时间.<br>同一类指令之间必须间隔一定时长. <br>同一类指令就是指令号相同. <br>例如所有聊天指令必须间隔500ms以上.<br><br>对于移动攻击类的指令, 很频繁, 用时间间隔限制不合适.<br>因为受网络抖动的影响, 可能会有多个指令集中地接收.<br>应该用平均指令数来限制.<br>如5s内指令个数不超过1000个.<br><br>对于受到限制的指令, 可以直接忽略. 也可以向客户端返回一个指令受限的指示.<br>对于确认为刷指令攻击的客户端, 就断开连接.<br><br>
<p>有的指令可以缓存,直到允许的时刻才转发给游戏服务器. 同类指令可以只保留最后一个指令.<br>
</p>
<br>
<br>（转载请注明来源于金庆的专栏）<br><br>
<br>  <img src ="http://www.cppblog.com/jinq0123/aggbug/96961.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-09-22 17:43 <a href="http://www.cppblog.com/jinq0123/archive/2009/09/22/96961.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost Serialization在网游中的应用实例</title><link>http://www.cppblog.com/jinq0123/archive/2009/09/21/96835.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 21 Sep 2009 05:32:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/09/21/96835.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/96835.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/09/21/96835.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/96835.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/96835.html</trackback:ping><description><![CDATA[Boost Serialization在网游中的应用实例<br><br>（转载请注明来源于金庆的专栏）<br><br>网游中需要在客户端和服务器之间传递多个字符串, <br>字符串的个数不定, 各个字符串的长度也不定.<br><br>对于长度变化不大的字符串, 可以用最大字符串长度:<br><br><span style="font-family: courier new; color: #700000;">struct MyCmd : public Cmd</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">{</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">&nbsp;&nbsp; &nbsp;WORD wNumber;</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">&nbsp;&nbsp; &nbsp;BYTE aStrings[MAX_SIZE][0];</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">};</span><br><br>这样会浪费一点带宽.<br><br>如果不这样, 可以用一个长的数据串, 在数据头部指出字符串的长度, <br>或者直接用'\0'分隔多个字符串, 如:<br><br><span style="color: #700000; font-family: courier new;">struct MyCmd : public Cmd</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">{</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;DWORD dwDataLen;</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;BYTE data[0];</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">};</span><br style="color: #700000; font-family: courier new;"><br>这样需要拼接和解析处理.<br><br>如果用序列化串, 可以很方便的解决该问题. <br><br><span style="font-family: courier new; color: #700000;">struct MyCmd : public Cmd</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">{</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">&nbsp;&nbsp; &nbsp;DWORD dwStrLen;</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">&nbsp;&nbsp; &nbsp;BYTE aSerializedStr[0];</span><br style="font-family: courier new; color: #700000;"><span style="font-family: courier new; color: #700000;">};</span><br style="font-family: courier new; color: #700000;"><br>利用boost::serialization可以序列化任意的std容器.<br><br>例如:<br><br><span style="color: #700000; font-family: courier new;">#include &lt;boost/archive/text_oarchive.hpp&gt;</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">#include &lt;boost/serialization/vector.hpp&gt;</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">...</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;std::vector&lt;std::string&gt; vStrings;</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;...</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;ostringstring oss;</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;boost::archive::text_oarchive oa(oss);</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;oa &amp; vStrings;</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;std::string sSerialized = oss.str();</span><br style="color: #700000; font-family: courier new;"><br>还原时:<br><br><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;std::vector&lt;std::string&gt; vNewStrings;</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;istringstream iss(sSerialized);</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;boost::archive::test_iarchive ia(iss);</span><br style="color: #700000; font-family: courier new;"><span style="color: #700000; font-family: courier new;">&nbsp;&nbsp; &nbsp;ia &amp; vNewStrings;</span><br>&nbsp;&nbsp; &nbsp;<br>如果是不同的std容器, 只需包含不同的serialization头文件. <br>如果未包含相应的serialization头文件, 编译会报serialize()函数未定义错误.<br>如果是自定义的数据结构, 只需定义serialize()即可, 详见boost文档.<br><br>序列化串也可应用于数据库保存. 实际上可以保存任意的数据结构.<br><br>&nbsp;<br><img src ="http://www.cppblog.com/jinq0123/aggbug/96835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-09-21 13:32 <a href="http://www.cppblog.com/jinq0123/archive/2009/09/21/96835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多角色控制系统</title><link>http://www.cppblog.com/jinq0123/archive/2009/09/10/95792.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 10 Sep 2009 05:33:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/09/10/95792.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/95792.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/09/10/95792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/95792.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/95792.html</trackback:ping><description><![CDATA[多角色控制系统<br><br>（转载请注明来源于金庆的专栏）<br><br>网游中的多角色控制系统(Multi-character Control, MCC)<br>就是你可以同时控制多个人物进行战斗.<br>卓越之剑（GE）就可以控制最多三个人物进行战斗。<br><br>目前的网游都是控制一个角色.<br>想要控制多个角色可以多开,即同时开多个游戏客户端,每个客户端登录一个角色.<br>多开的麻烦是需要切换窗口.<br>对于3D网游来说,客户端极耗资源,所以多开会造成系统很卡.<br><br>MCC给网游带来了新的气息. 从此不必多开. 有点像单机游戏了.<br><br>从程序实现上来看, MCC比多开效率高, <br>因为场景刷新的数据只需发送一份, 处理一次就够了.<br><br>MCC的概念还淡化了角色和NPC之间的差别.<br>一个客户端可以控制多个角色, 而一个NPC控制器可以控制一群NPC.<br>NPC的AI可以独立出来, 对服务器来说, 角色的控制与NPC的控制是相同的.<br><br>如果一个NPC AI进程或线程只控制一个NPC, 这种开销太大.<br>如果一个NPC AI进程控制一个场景内的所有NPC, <br>场景刷新数据只需发送一次, 处理一次, 这样就很合理.<br>这种NPC控制模式应用到角色控制上就是MCC.<br><br>如果MCC中可以有角色AI, NPC控制中可以有GM手工控制NPC, 这样两者差别就更小了.<br><br><br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/95792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-09-10 13:33 <a href="http://www.cppblog.com/jinq0123/archive/2009/09/10/95792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用BOOST_ASSERT代替assert</title><link>http://www.cppblog.com/jinq0123/archive/2009/08/21/94027.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 21 Aug 2009 08:32:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/08/21/94027.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/94027.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/08/21/94027.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/94027.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/94027.html</trackback:ping><description><![CDATA[用BOOST_ASSERT代替assert<br><br>（转载请注明来源于金庆的专栏）<br><br>断言assert()简单地输出错误信息并调用abort()退出是相当好用的功能.<br>错误信息包括文件名, 代码行, 及出错的表达式.<br>(如果能像Java, Python那样获取出错时的调用栈(traceback)就更好了,<br>可惜C++中好像无法得到调用栈?)<br><br>出于某些特殊的目的, 可以用BOOST_ASSERT()来代替assert().<br>BOOST_ASSERT()比assert()更灵活, (虽然也没有调用栈信息), <br>其基本的行为与assert()一致.<br><br>有两点扩展功能:<br><br>1. 可以定义BOOST_DISABLE_ASSERTS来停用BOOST_ASSERT().<br><br>assert通过定义NDEBUG来停用, 但是有时候想要发布一个调试版, <br>不能定义NDEBUG, 无法停用assert(). <br>用BOOST_ASSERT()就多了一个控制选项, 即可以在调试版中停用断言.<br><br>2. 可以定义BOOST_ENABLE_ASSERT_HANDLER, 来调用自定义的断言出错函数.<br><br>如果定义了 BOOST_ENABLE_ASSERT_HANDLER，<br>BOOST_ASSERT 失败则调用 ::boost::assertion_failed().<br>如果未定义BOOST_ENABLE_ASSERT_HANDLER，则会调用标准的assert().<br><br>boost/assert.hpp中只声明了assertion_failed(), 需要自己定义.<br>它有4个参数, 分别是出错表达式串, 函数名, 文件名, 行号.<br><br>有了自定义的断言出错处理函数, 就可以实现断言出错时记录日志并续继执行.<br>(个人觉得这不是个好主意, 但被要求如此实现, 只好努力去满足).<br>绝妙的是, 可以通过宏来控制自己想要的断言行为.<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/94027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-08-21 16:32 <a href="http://www.cppblog.com/jinq0123/archive/2009/08/21/94027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>函数参数的理想个数</title><link>http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 03 Aug 2009 09:35:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/92059.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/92059.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/92059.html</trackback:ping><description><![CDATA[摘译自: <br><br>Clean Code<br>A Handbook of Agile<br>Software Craftsmanship<br>Robert C. Martin<br><br><br>Function Arguments<br><br>The ideal number of arguments for a function is<br>zero (niladic). Next comes one (monadic), followed<br>closely by two (dyadic). Three arguments (triadic)<br>should be avoided where possible. More than three<br>(polyadic) requires very special justification—and<br>then shouldn&#8217;t be used anyway.<br><br>函数参数<br><br>函数参数的理想个数是零个（零元）。<br>其次是一个（一元），<br>紧接下来是两个（二元）。<br>三个参数（三元）应尽可能地避免。<br>三个以上的参数（多元）需要非常特殊的理由<br>————否则无论如何都不应该。<br><br>（转载请注明来源于金庆的专栏）<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/92059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-08-03 17:35 <a href="http://www.cppblog.com/jinq0123/archive/2009/08/03/92059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网游反外挂图形验证机制的设计</title><link>http://www.cppblog.com/jinq0123/archive/2009/07/23/90913.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 23 Jul 2009 03:54:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/07/23/90913.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/90913.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/07/23/90913.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/90913.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/90913.html</trackback:ping><description><![CDATA[网游反外挂图形验证机制的设计<br><br>（转载请注明来源于金庆的专栏）<br><br>为了防止外挂的自动操作, 在适当的时候会弹出一个图形验证码, <br>要求手工输入正确的验证码才允许操作.<br><br>例如登录时, 交易时, 有一定概率要求验证.<br><br>图形验证就是随机取几个字符, 生成加扰变形图形, 发往客户端,<br>客户端返回验证码与记录的字符一致时就算通过.<br><br>可以建立一个图形验证机制, 使图形验证可以插入到任何现有流程之内.<br><br>例如可以在交易中插入图形验证, 而无需更改原来的交易指令.<br>在收到客户端请求交易时, 如需要验证, 则向客户端发送验证图形,<br>同时缓存该交易请求.<br>如果正处于等待验证中, 则应该只对验证回复进行处理.<br>待客户端返回正确验证码时, 取出缓存的交易请求进入正常的交易处理.<br><br>图形验证的指令设计可适用于任意流程.<br><br>1. Svr-&gt;Clt, 发送验证码图片<br>2. Clt-&gt;Svr, 返回验证码, 如错误则发4<br>3. Clt-&gt;Svr, 看不清, 请求重发图片, 发1<br>4. Svr-&gt;Clt, 验证码错误, 重发图片<br>5. Clt-&gt;Svr, 放弃验证<br><br><br>
<br> <img src ="http://www.cppblog.com/jinq0123/aggbug/90913.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-07-23 11:54 <a href="http://www.cppblog.com/jinq0123/archive/2009/07/23/90913.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用脚本实现副本</title><link>http://www.cppblog.com/jinq0123/archive/2009/07/16/90279.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 16 Jul 2009 13:40:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/07/16/90279.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/90279.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/07/16/90279.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/90279.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/90279.html</trackback:ping><description><![CDATA[用脚本实现副本<br><br>（转载请注明来源于金庆的专栏）<br><br>副本是当前网游中的一大热点, 创建出几个好玩的副本就能吸引大量的玩家.<br>不管是PVP还是PVE副本, 原理就是对抗双方或多方的力量是可控制的, <br>如副本限制进入角色的等级和人数; 并且可以多个相同副本同时运行, 互不干拢,<br>副本就像是专用的服务器.<br>这两点在普通地图上是无法实现的, 普通地图上BOSS会被群殴，并且只有一个BOSS不够分.<br><br>设计:<br><br>1. 创建和进入副本.<br>&nbsp; 通过NPC对话或使用物品. 这已经脚本化了. 只需一个脚本命令, 参数是副本名.<br>&nbsp; <br>2. 副本场景.<br>&nbsp; 已经是可配置.<br>&nbsp; <br>3. 副本计分和奖励.<br>&nbsp; 需要建立统一规则.<br><br>4. 副本内特殊事件.<br>&nbsp; 暂时难以处理. <br><br><img src ="http://www.cppblog.com/jinq0123/aggbug/90279.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-07-16 21:40 <a href="http://www.cppblog.com/jinq0123/archive/2009/07/16/90279.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DOS批处理中字符替换的小技巧</title><link>http://www.cppblog.com/jinq0123/archive/2009/07/06/89363.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 06 Jul 2009 06:46:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/07/06/89363.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/89363.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/07/06/89363.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/89363.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/89363.html</trackback:ping><description><![CDATA[DOS批处理中字符替换的小技巧<br><br>参考: http://www.cn-dos.net/forum/viewthread.php?tid=36953<br><br><span style="color: #0031c4;">set newtime=%time:~0,2%%time:~3,2%</span><br><br>可以产生HHMM形式的时间字符串, 但是当0..9点时, 小时数只有1位, 前面会产生一个空格而不是0.<br><br><span style="color: #0031c4;">echo %newtime: =0%</span><br><br>将字符串中的空格替换成0.<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/89363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-07-06 14:46 <a href="http://www.cppblog.com/jinq0123/archive/2009/07/06/89363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(Python编程)Pickle对象</title><link>http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 03 Jul 2009 08:37:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/89167.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/89167.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/89167.html</trackback:ping><description><![CDATA[<p>Programming Python, 3rd Edition 翻译<br>最新版本见：<a href="http://wiki.woodpecker.org.cn/moin/PP3eD">http://wiki.woodpecker.org.cn/moin/PP3eD</a>
<br></p>
<p><br></p>
<p>19.4. Pickled Objects <br>
<br>
19.4. Pickle对象 <br>
<br>
</p>
<p>Probably
the biggest limitation of DBM keyed files is in what they can store:
data stored under a key must be a simple text string. If you want to
store Python objects in a DBM file, you can sometimes manually convert
them to and from strings on writes and reads (e.g., with str and eval
calls), but this takes you only so far. For arbitrarily complex Python
objects such as class instances and nested data structures, you need
something more. Class instance objects, for example, cannot be later
re-created from their standard string representations. Custom to-string
conversions are error prone and not general. <br>
<br>
</p>
<p>DBM
键控文件（DBM keyed
file）最大的限制也许在于他们可以存储的东西：一个键值下存储的数据必须是个简单文本字符串。如果您想要在DBM文件中储存Python对象，有时您
可以在读写的时候，手动进行与字符串的转换（例如，用str和eval调用），但只能做到这样。对任意复杂的Python对象，如类实例和嵌套的数据结
构，您需要更多的东西。例如，类实例对象以后无法从其标准字符串表达（string
representation）重建。自定义的到字符串的转换容易出错，并且不通用。 <br>
<br>
</p>
<p>The
Python pickle module, a standard part of the Python system, provides
the conversion step needed. It converts nearly arbitrary Python
in-memory objects to and from a single linear string format, suitable
for storing in flat files, shipping across network sockets between
trusted sources, and so on. This conversion from object to string is
often called serializationarbitrary data structures in memory are
mapped to a serial string form. <br>
<br>
</p>
<p>Python
系统的标准部件，pickle模块，提供了所需的转换步骤。它可以将几乎任意的Python内存对象，转换为单一线性的字符串格式，使之适于无格式文件存
储，或在可靠来源之间跨越网络套接口传输等等，并可反向转换。这种从对象到字符串的转换通常被称为序列化（serialization）：将内存中的任意
数据结构映射为串行字符串形式。 <br>
<br>
</p>
<p>The
string representation used for objects is also sometimes referred to as
a byte stream, due to its linear format. It retains all the content and
references structure of the original in-memory object. When the object
is later re-created from its byte string, it will be a new in-memory
object identical in structure and value to the original, though located
at a different memory address. The re-created object is effectively a
copy of the original. <br>
<br>
</p>
<p>对象的字符串表达由于其线性的格式，有时也被称为字节流。它包含了原始内存中对象的所有内容和引用结构。当对象后来从其字节串重建时，内存中新建的对象与原对象具有相同的结构和值，但位于不同的内存地址。该重建对象实际上是原对象的复制。 <br>
<br>
</p>
<p>Pickling
works on almost any Python datatypenumbers, lists, dictionaries, class
instances, nested structures, and moreand so is a general way to store
data. Because pickles contain native Python objects, there is almost no
database API to be found; the objects stored are processed with normal
Python syntax when they are later retrieved. <br>
<br>
</p>
<p>Pickle可用于几乎所有的Python数据类型：数字、列表、字典、类实例、嵌套结构，等等，因此它是存储数据的通用方法。因为pickle包含的是Python本地对象，所以几乎没有数据库的API；对象存储与处理及后来的提取用的都是通常的Python语法。 <br>
<br>
</p>
<p>19.4.1. Using Object Pickling <br>
<br>
</p>
<p>19.4.1. 使用对象pickle <br>
<br>
</p>
<p>Pickling
may sound complicated the first time you encounter it, but the good
news is that Python hides all the complexity of object-to-string
conversion. In fact, the pickle module 's interfaces are incredibly
simple to use. For example, to pickle an object into a serialized
string, we can either make a pickler and call its methods or use
convenience functions in the module to achieve the same effect: <br>
<br>
</p>
<p>第
一次听到pickle，可能觉得有点复杂，但好消息是，Python隐藏了所有从对象到字符串转换的复杂性。事实上，pickle模块的接口简单易用，简
直令人难以置信。例如，要pickle对象到一个序列化字符串，我们可以生成一个pickler，并调用其方法，或使用模块中的便捷函数来达到相同的效
果： <br>
<br>
</p>
<p>&#160;</p>
<pre>P = pickle.Pickler( file) <br></pre>
<p>Make a new pickler for pickling to an open output file object file. <br>
生成一个新的pickler，用来pickle到一个打开的输出文件对象file。 <br>
<br>
</p>
<p>&#160;</p>
<pre>P.dump( object) <br></pre>
<p>Write an object onto the pickler's file/stream. <br>
写一个对象到pickler的文件/流。 <br>
<br>
</p>
<p>&#160;</p>
<pre>pickle.dump( object, file) <br></pre>
<p>Same as the last two calls combined: pickle an object onto an open file. <br>
等同于上两个调用的组合：pickle对象到一个打开的文件。 <br>
<br>
</p>
<p>&#160;</p>
<pre>string = pickle.dumps( object) <br></pre>
<p>Return the pickled representation of object as a character string. <br>
返回一个字符串作为已pickle对象的表达。 <br>
<br>
</p>
<p>Unpickling
from a serialized string back to the original object is similarboth
object and convenience function interfaces are available: <br>
<br>
</p>
<p>从一个序列化字符串unpickle回原始对象是类似的，可以用对象也可以用便捷函数接口： <br>
<br>
</p>
<p>&#160;</p>
<pre>U = pickle.Unpickler( file) <br></pre>
<p>Make an unpickler for unpickling from an open input file object file. <br>
生成一个unpickler，用来从一个打开的文件对象file unpickle。 <br>
<br>
</p>
<p>&#160;</p>
<pre>object = U.load( )<br></pre>
<p>Read an object from the unpickler's file/stream. <br>
从unpickler的文件/流读取一个对象。 <br>
<br>
</p>
<p>&#160;</p>
<pre>object = pickle.load( file) <br></pre>
<p>Same as the last two calls combined: unpickle an object from an open file. <br>
等同于上两个调用的组合：从一个打开的文件unpickle一个对象。 <br>
<br>
</p>
<p>&#160;</p>
<pre>object = pickle.loads( string) <br></pre>
<p>Read an object from a character string rather than a file. <br>
从字符串读取一个对象，而不是从文件。 <br>
<br>
</p>
<p>Pickler
and Unpickler are exported classes. In all of the preceding cases, file
is either an open file object or any object that implements the same
attributes as file objects: <br>
<br>
</p>
<p>Pickler和Unpickler是导出类。在上述所有情况下，file是个已打开的文件对象，或者是实现了以下文件对象属性的任何对象： <br>
<br>
</p>
<p>Pickler calls the file's write method with a string argument. <br>
<br>
</p>
<p>Pickler会调用文件的write方法，参数是个字符串。 <br>
<br>
</p>
<p>Unpickler calls the file's read method with a byte count, and readline without arguments. <br>
<br>
</p>
<p>Unpickler会调用文件的read方法，参数是字节数，以及readline，无参数。 <br>
<br>
</p>
<p>Any
object that provides these attributes can be passed in to the file
parameters. In particular, file can be an instance of a Python class
that provides the read/write methods (i.e., the expected file-like
interface). This lets you map pickled streams to in-memory objects with
classes, for arbitrary use. For instance, the StringIO standard library
module discussed in Chapter 3 provides classes that map file calls to
and from in-memory strings. <br>
<br>
</p>
<p>任
何提供这些属性的对象都可以作为file参数传入。特别是，file可以是一个提供了读/写方法的Python类实例（即预期的类似文件的接口）。这让您
可以用类映射pickle流到内存对象，并可任意使用。例如，第3章讨论的标准库模块StringIO提供的类，它们可映射文件调用到内存字符串或反之。
<br>
<br>
</p>
<p>This
hook also lets you ship Python objects across a network, by providing
sockets wrapped to look like files in pickle calls at the sender, and
unpickle calls at the receiver (see the sidebar "Making Sockets Look
Like Files," in Chapter 13, for more details). In fact, for some,
pickling Python objects across a trusted network serves as a simpler
alternative to network transport protocols such as SOAP and XML-RPC;
provided that Python is on both ends of the communication (pickled
objects are represented with a Python-specific format, not with XML
text). <br>
<br>
</p>
<p>该
挂钩也可以让您通过网络传输Python对象，只要封装套接口，使之看上去像发送端pickle调用中的文件，以及像接收端unpickle调用中的文件
（详见第13章侧栏&#8220;使套接口看上去像文件&#8221;）。事实上，对一些人来说，pickle
Python对象并在一个值得信赖的网络上传输，是替代如SOAP和XML-RPC之类网络传输协议的一个简单方法；只要通信的两端都有Python（被
pickle的对象是用Python专有的格式表达的，而不是用XML文本）。 <br>
<br>
</p>
<p>19.4.2. Picking in Action <br>
<br>
</p>
<p>19.4.2. Pickle实战 <br>
<br>
</p>
<p>In more typical use, to pickle an object to a flat file, we just open the file in write mode and call the dump function: <br>
<br>
</p>
<p>典型的使用情况是，pickle对象到无格式文件，我们只需以写模式打开文件，并调用dump函数： <br>
<br>
</p>
<p>&#160;</p>
<pre>% python<br>&gt;&gt;&gt; table = {'a': [1, 2, 3],<br>             'b': ['spam', 'eggs'],<br>             'c': {'name':'bob'}}<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; mydb  = open('dbase', 'w')<br>&gt;&gt;&gt; pickle.dump(table, mydb)<br></pre>
<p><br>
<br>
</p>
<p>Notice
the nesting in the object pickled herethe pickler handles arbitrary
structures. To unpickle later in another session or program run, simply
reopen the file and call load: <br>
<br>
</p>
<p>注意这个被pickle对象中的嵌套：pickler可以处理任意结构。然后，在另一个会话或程序中unpickle，只要重新打开该文件，并调用load： <br>
<br>
</p>
<p>&#160;</p>
<pre>% python<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; mydb  = open('dbase', 'r')<br>&gt;&gt;&gt; table = pickle.load(mydb)<br>&gt;&gt;&gt; table<br>{'b': ['spam', 'eggs'], 'a': [1, 2, 3], 'c': {'name': 'bob'}}<br></pre>
<p><br>
<br>
</p>
<p>The
object you get back from unpickling has the same value and reference
structure as the original, but it is located at a different address in
memory. This is true whether the object is unpickled in the same or a
future process. In Python-speak, the unpickled object is == but is not
is: <br>
<br>
</p>
<p>unpickle所得的对象具有与原对象相同的值和引用结构，但它位于不同的内存地址。无论在同一进程或另一进程unpickle，都是这样。用Python的话来说，unpickle后的对象是&#8220;==&#8221;关系，但不是&#8220;is&#8221;关系： <br>
<br>
</p>
<p>&#160;</p>
<pre>% python<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; f = open('temp', 'w')<br>&gt;&gt;&gt; x = ['Hello', ('pickle', 'world')]           # list with nested tuple<br>&gt;&gt;&gt; pickle.dump(x, f)<br>&gt;&gt;&gt; f.close( )                                   # close to flush changes<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; f = open('temp', 'r')<br>&gt;&gt;&gt; y = pickle.load(f)<br>&gt;&gt;&gt; y<br>['Hello', ('pickle', 'world')]<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; x == y, x is y<br>(True, False)<br></pre>
<p><br>
<br>
</p>
<p>To
make this process simpler still, the module in Example 19-1 wraps
pickling and unpickling calls in functions that also open the files
where the serialized form of the object is stored. <br>
<br>
</p>
<p>为了让这一过程更简单，例19-1中的模块把pickle和unpickle调用封装在函数中，在函数中同时还打开文件，并将对象的序列化存储在该文件中。 <br>
<br>
</p>
<p>Example 19-1. PP3E\Dbase\filepickle.py </p>
<div class="codearea" dir="ltr" lang="en">
<script type="text/javascript">
function isnumbered(obj) {
  return obj.childNodes.length && obj.firstChild.childNodes.length && obj.firstChild.firstChild.className == 'LineNumber';
}
function nformat(num,chrs,add) {
  var nlen = Math.max(0,chrs-(''+num).length), res = '';
  while (nlen>0) { res += ' '; nlen-- }
  return res+num+add;
}
function addnumber(did, nstart, nstep) {
  var c = document.getElementById(did), l = c.firstChild, n = 1;
  if (!isnumbered(c))
    if (typeof nstart == 'undefined') nstart = 1;
    if (typeof nstep  == 'undefined') nstep = 1;
    n = nstart;
    while (l != null) {
      if (l.tagName == 'SPAN') {
        var s = document.createElement('SPAN');
        s.className = 'LineNumber'
        s.appendChild(document.createTextNode(nformat(n,4,' ')));
        n += nstep;
        if (l.childNodes.length)
          l.insertBefore(s, l.firstChild)
        else
          l.appendChild(s)
      }
      l = l.nextSibling;
    }
  return false;
}
function remnumber(did) {
  var c = document.getElementById(did), l = c.firstChild;
  if (isnumbered(c))
    while (l != null) {
      if (l.tagName == 'SPAN' && l.firstChild.className == 'LineNumber') l.removeChild(l.firstChild);
      l = l.nextSibling;
    }
  return false;
}
function togglenumber(did, nstart, nstep) {
  var c = document.getElementById(did);
  if (isnumbered(c)) {
    remnumber(did);
  } else {
    addnumber(did,nstart,nstep);
  }
  return false;
}
</script>
<script type="text/javascript">
document.write('<a href="#" href_cetemp="#" onclick="return togglenumber(\'ca-fb42528cb4c20d066e06b836307a75fa8e016e1b_000\', 1, 1);" \
                class="codenumbers">切换行号显示<\/a>');
</script>
<pre dir="ltr" id="CA-fb42528cb4c20d066e06b836307a75fa8e016e1b_000" lang="en">   1 import pickle<br>   2 <br>   3 def saveDbase(filename, object):<br>   4     file = open(filename, 'w')<br>   5     pickle.dump(object, file)          # pickle to file<br>   6     file.close( )                     # any file-like object will do<br>   7 <br>   8 def loadDbase(filename):<br>   9     file = open(filename, 'r')<br>  10     object = pickle.load(file)         # unpickle from file<br>  11     file.close( )                     # re-creates object in memory<br>  12     return object<br></pre>
</div>
<p><br>
<br>
</p>
<p>To
store and fetch now, simply call these module functions; here they are
in action managing a fairly complex structure with multiple references
to the same nested objectthe nested list called L at first is stored
only once in the file: <br>
<br>
</p>
<p>现在，存储和提取时只需调用这些模块函数；以下实例是个相当复杂的结构，具有对同一嵌套对象的多重引用，该嵌套列表，即第1个L，在文件中只会保存一次： <br>
<br>
</p>
<p>&#160;</p>
<pre>C:\...\PP3E\Dbase&gt;python<br>&gt;&gt;&gt; from filepickle import *<br>&gt;&gt;&gt; L = [0]<br>&gt;&gt;&gt; D = {'x':0, 'y':L}<br>&gt;&gt;&gt; table = {'A':L, 'B':D}              # L appears twice<br>&gt;&gt;&gt; saveDbase('myfile', table)          # serialize to file<br><br>C:\...\PP3E\Dbase&gt;python<br>&gt;&gt;&gt; from filepickle import *<br>&gt;&gt;&gt; table = loadDbase('myfile')         # reload/unpickle<br>&gt;&gt;&gt; table<br>{'B': {'x': 0, 'y': [0]}, 'A': [0]}<br>&gt;&gt;&gt; table['A'][0] = 1                   # change shared object<br>&gt;&gt;&gt; saveDbase('myfile', table)          # rewrite to the file<br><br>C:\...\PP3E\Dbase&gt;python<br>&gt;&gt;&gt; from filepickle import *<br>&gt;&gt;&gt; print loadDbase('myfile')           # both L's updated as expected<br>{'B': {'x': 0, 'y': [1]}, 'A': [1]}<br></pre>
<p><br>
<br>
</p>
<p>Besides
built-in types like the lists, tuples, and dictionaries of the examples
so far, class instances may also be pickled to file-like objects. This
provides a natural way to associate behavior with stored data (class
methods process instance attributes) and provides a simple migration
path (class changes made in module files are automatically picked up by
stored instances). Here's a brief interactive demonstration: <br>
<br>
</p>
<p>除
了内置的类型，如以上例子中的列表，元组和字典，类实例也可被pickle到类似文件的对象中。这提供了一个自然的方式来关联行为与存储的数据（类方法处
理实例的属性），并提供了一条简单的迁移路径（被存储的实例将自动获得模块文件中对类的更改）。以下是个简短的交互演示： <br>
<br>
</p>
<p>&#160;</p>
<pre>&gt;&gt;&gt; class Rec:<br>        def _ _init_ _(self, hours):<br>            self.hours = hours<br>        def pay(self, rate=50):<br>            return self.hours * rate<br><br>&gt;&gt;&gt; bob = Rec(40)<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; pickle.dump(bob, open('bobrec', 'w'))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; rec = pickle.load(open('bobrec'))<br>&gt;&gt;&gt; rec.hours<br>40<br>&gt;&gt;&gt; rec.pay( )<br>2000<br></pre>
<p><br>
<br>
</p>
<p>We'll
explore how this works in more detail in conjunction with shelves later
in this chapteras we'll see, although the pickle module can be used
directly, it is also the underlying translation engine in both shelves
and ZODB databases. <br>
<br>
</p>
<p>我们将与本章下面的shelve一起详细探讨这是如此工作的。我们将会看到，虽然pickle模块可直接使用，但它也是shelve和ZODB数据库的底层翻译引擎。 <br>
<br>
</p>
<p>In fact, Python can pickle just about anything, except for: <br>
<br>
</p>
<p>事实上，Python可以pickle任何东西，除了： <br>
<br>
</p>
<p>Compiled
code objects; functions and classes record just their names in pickles,
to allow for later reimport and automatic acquisition of changes made
in module files. <br>
<br>
</p>
<p>编译的代码对象；函数和类在pickle中只是记录了它们的名字，以便后来重新导入和自动获取模块文件中的更改。 <br>
<br>
</p>
<p>Instances
of classes that do not follow class importability rules (more on this
at the end of the section "Shelve Files," later in this chapter). <br>
<br>
</p>
<p>不遵守类可导入规则（class importability rule）的类实例（本章后面&#8220;Shelve文件&#8221;一节的尾部有更多相关内容）。 <br>
<br>
</p>
<p>Instances
of some built-in and user-defined types that are coded in C or depend
upon transient operating system states (e.g., open file objects cannot
be pickled). <br>
<br>
</p>
<p>用C编码的或依赖于操作系统瞬态的一些内置的和用户定义类型的实例（例如，打开的文件对象无法pickle）。 <br>
<br>
</p>
<p>A <a class="nonexistent" href="http://wiki.woodpecker.org.cn/moin/PicklingError">PicklingError</a> is raised if an object cannot be pickled. <br>
<br>
</p>
<p>如果对象不能pickle，会引发<a class="nonexistent" href="http://wiki.woodpecker.org.cn/moin/PickleError">PickleError</a>。 <br>
<br>
</p>
<p>19.4.3. Pickler Protocols and cPickle <br>
<br>
</p>
<p>19.4.3. Pickler协议和cPickle <br>
<br>
</p>
<p>In
recent Python releases, the pickler introduced the notion of
protocolsstorage formats for pickled data. Specify the desired protocol
by passing an extra parameter to the pickling calls (but not to
unpickling calls: the protocol is automatically determined from the
pickled data): <br>
<br>
</p>
<p>在最近的Python版本中，pickler推出了协议的概念：pickle数据的保存格式。通过pickle调用时传入一个额外的参数，可指定所需的协议（但unpickle调用不需要：协议是自动从已pickle的数据确定的）： <br>
<br>
</p>
<p>&#160;</p>
<pre>pickle.dump(object, file, protocol)<br></pre>
<p><br>
<br>
</p>
<p>Pickled
data may be created in either text or binary protocols. By default, the
storage protocol is text (also known as protocol 0). In text mode, the
files used to store pickled objects may be opened in text mode as in
the earlier examples, and the pickled data is printable ASCII text,
which can be read (it's essentially instructions for a stack machine). <br>
<br>
</p>
<p>Pickle
数据可以按文本协议或二进制协议产生。默认情况下，存储协议是文本协议（也称为0号协议）。在文本模式下，用来存储pickle对象的文件可以用文本模式
打开，如上述的例子，并且pickle的数据是可打印的ASCII文本，并且是可读的（这基本上是对堆栈机实现的指示）。 <br>
<br>
</p>
<p>The
alternative protocols (protocols 1 and 2) store the pickled data in
binary format and require that files be opened in binary mode (e.g.,
rb, wb). Protocol 1 is the original binary format; protocol 2, added in
Python 2.3, has improved support for pickling of new-style classes.
Binary format is slightly more efficient, but it cannot be inspected.
An older option to pickling calls, the bin argument, has been subsumed
by using a pickling protocol higher than 0. The pickle module also
provides a HIGHEST_PROTOCOL variable that can be passed in to
automatically select the maximum value. <br>
<br>
</p>
<p>其
他协议（1号和2号协议
）以二进制格式存储pickle数据，并要求文件以二进制模式打开（例如：rb、wb）。1号协议是原始二进制格式；2号协议是Python
2.3增加的，它改善了对新型类pickle的支持。二进制格式效率更高一点，但它无法进行查看。旧的pickle调用有一个选项，即bin参数，现已被
归入使用大于0的协议。pickle模块还提供了一个HIGHEST_PROTOCOL变量，传入它可以自动选择最大的协议值。 <br>
<br>
</p>
<p>One
note: if you use the default text protocol, make sure you open pickle
files in text mode later. On some platforms, opening text data in
binary mode may cause unpickling errors due to line-end formats on
Windows: <br>
<br>
</p>
<p>注意：如果您使用默认的文本协议，以后请务必以文本模式打开pickle文件。在一些平台上，因为Windows的行尾格式不同，以二进制模式打开文本数据可能会导致unpickle错误: <br>
<br>
</p>
<p>&#160;</p>
<pre>&gt;&gt;&gt; f = open('temp', 'w')                  # text mode file on Windows<br>&gt;&gt;&gt; pickle.dump(('ex', 'parrot'), f)       # use default text protocol<br>&gt;&gt;&gt; f.close( ) <br>&gt;&gt;&gt;<br>&gt;&gt;&gt; pickle.load(open('temp', 'r'))         # OK in text mode<br>('ex', 'parrot')<br>&gt;&gt;&gt; pickle.load(open('temp', 'rb'))        # fails in binary<br>Traceback (most recent call last):<br>  File "&lt;pyshell#337&gt;", line 1, in -toplevel-<br>    pickle.load(open('temp', 'rb'))<br> ...lines deleted...<br>ValueError: insecure string pickle<br></pre>
<p><br>
<br>
</p>
<p>One
way to sidestep this potential issue is to always use binary mode for
your files, even for the text pickle protocol. Since you must open
files in binary mode for the binary pickler protocols anyhow (higher
than the default 0), this isn't a bad habit to get into: <br>
<br>
</p>
<p>回避这个潜在问题的方法之一是，总是使用二进制模式的文件，即使是用文本pickle协议。至少对于二进制pickler协议（高于默认0），您必须以二进制模式打开文件，所以这不是一个坏习惯： <br>
<br>
</p>
<p>&#160;</p>
<pre>&gt;&gt;&gt; f = open('temp', 'wb')                 # create in binary mode<br>&gt;&gt;&gt; pickle.dump(('ex', 'parrot'), f)       # use text protocol<br>&gt;&gt;&gt; f.close( )<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; pickle.load(open('temp', 'rb'))<br>('ex', 'parrot')<br>&gt;&gt;&gt; pickle.load(open('temp', 'r'))<br>('ex', 'parrot')<br></pre>
<p><br>
<br>
</p>
<p>Refer
to Python's library manual for more information on the pickler. Also
check out marshal, a module that serializes an object too, but can
handle only simple object types. pickle is more general than marshal
and is normally preferred. <br>
<br>
</p>
<p>请参考Python库手册，以了解更多pickler的信息。另外，请查阅marshal，它也是一个序列化对象的模块，但只能处理简单对象类型。pickle比marshal更通用，并通常是首选。 <br>
<br>
</p>
<p>And
while you are flipping (or clicking) through that manual, be sure to
also see the entries for the cPickle modulea reimplementation of pickle
coded in C for faster performance. You can explicitly import cPickle
for a substantial speed boost; its chief limitation is that you cannot
subclass its versions of Pickle and Unpickle because they are
functions, not classes (this is not required by most programs). The
pickle and cPickle modules use compatible data formats, so they may be
used interchangeably. <br>
<br>
</p>
<p>而
当你翻看（或点击）Python手册时，请一定也要看看cPickle模块的条目，它是pickle的C语言实现，性能上更快。您可以显式导入
cPickle替代pickle，以大幅提升速度；其主要的限制是，你不能继承该版本的Pickle和Unpickle，因为它们是函数，而不是类（多数
程序并不要求它们是类）。pickle和cPickle模块使用兼容的数据格式，所以它们可以互换使用。 <br>
<br>
</p>
<p>If
it is available in your Python, the shelve module automatically chooses
the cPickle module for faster serialization, instead of pickle. I
haven't explained shelve yet, but I will now. <br>
<br>
</p>
如果您的Python中有shelve模块，它会自动选用cPickle模块，而不是pickle，以达到更快的序列化。我还没有解释过shelve，但我马上就会讲到它。 <br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/89167.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-07-03 16:37 <a href="http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SVN中邪恶的replace</title><link>http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 18 Jun 2009 06:53:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/87977.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/87977.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/87977.html</trackback:ping><description><![CDATA[SVN中邪恶的replace<br><br>（转载请注明来源于金庆的专栏）<br><br>用TSVN客户端删除一个文件, 然后再新建一个同名文件, <br>可以看到该文件上的图标被打上了TSVN的小红叉.<br>然后Add, Commit, 就会出现一条replace记录.<br>replace的操作会有个提示, 就是Add(as replacement)...命令项与普通的Add不同．<br><br>意思应该是该文件被替换了.<br><br>邪恶之处是以前的更改日志显示不出来了.<br>用revision graph可以看到所有历史, 只是在replace处是断裂的.<br>也就是说替换的效果是重新开启一个文件的更改记录, 隐藏之前的记录.<br>我想不出什么情况下需要这种功能.<br><br>更邪恶的是, revert changes from this revision会失败(TSVN 1.4.3).<br>错误原因是该文件的上个版本不存在.<br>好像所的Add操作都是无法revert, 应该算是个缺陷吧?<br><br>为了还原该替换，须删除该文件, 然后revert changes from this revision.<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/87977.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-06-18 14:53 <a href="http://www.cppblog.com/jinq0123/archive/2009/06/18/87977.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>当心虚函数重载(overloaded-virtual)</title><link>http://www.cppblog.com/jinq0123/archive/2009/05/22/85378.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 22 May 2009 05:59:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/05/22/85378.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/85378.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/05/22/85378.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/85378.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/85378.html</trackback:ping><description><![CDATA[当心虚函数重载(overloaded-virtual)<br><br>（转载请注明来源于金庆的专栏）<br><br>为网游万王之王3(KOK3)服务器添加新功能的时候, <br>发现某个类成员函数应该是const函数, 因为我的const函数要调用该函数, <br>顺手就加上了const.<br><br>再顺便看到该类有好多个明显是getter函数, 所以都加上了const.<br>编译没错就提交了.<br><br>结果没多久测试就发现了新版本的一个错误, 表现在其他功能上, <br>但由同事纠错后发现是我添加const的后果.<br><br>原来添加const的成员函数中, 有一个是virtual函数, 加了const后与子类的函数原型就不符了.<br>子类的函数成为父类虚函数的一个重载, 使virtual失效, 多态性无法表现出来.<br>解决方法就是子类的相应虚函数中也添加const.<br><br>教训: 更改虚函数原型时, 必须同时更改父类和子类.<br><br>gcc中有个-Woverloaded-virtual警告选项, 会报告这种虚函数重载.<br><br>我在Makefile中打开了-Woverloaded-virtual, 再次编译时就产生了许多警告.<br>大多数警告是正确的函数重载, 但还是发现了一个与我相同的错误, <br>这次是函数参数const有区别, 我发给相关人员处理了.<br><br>因为开了-Werror, 所有警告都会造成编译失败, <br>所以我们不能在Makefile中加入-Woverloaded-virtual警告选项.<br><br>代码示例:<br><br><span style="font-family: courier new; color: #600000;">class A</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">{</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">&nbsp;&nbsp; &nbsp;virtual void f() {};</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">};</span><br style="font-family: courier new; color: #600000;"><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">class B : public A</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">{</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">&nbsp;&nbsp; &nbsp;virtual void f() const {};</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">};</span><br style="font-family: courier new; color: #600000;"><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">int main()</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">{</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">&nbsp;&nbsp; &nbsp;return 0;</span><br style="font-family: courier new; color: #600000;"><span style="font-family: courier new; color: #600000;">}</span><br><br><span style="font-family: courier new; color: #0010ff;">$ g++ main.cpp -Woverloaded-virtual</span><br style="font-family: courier new; color: #0010ff;"><span style="font-family: courier new; color: #0010ff;">main.cpp:3: warning: `virtual void A::f()' was hidden</span><br style="font-family: courier new; color: #0010ff;"><span style="font-family: courier new; color: #0010ff;">main.cpp:8: warning:&nbsp;&nbsp; by `virtual void B::f() const'</span><br><br>Google的代码规范中要求所有子类的虚函数中都加上virtual, 是很有道理的.<br>虽然只要与父类虚函数签名相同, 加不加virtual都是虚函数,<br>但是以后更改函数签名时, 看到virtual很容易知道它是虚函数, 需要父类子类同时更改.<br><br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/85378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-05-22 13:59 <a href="http://www.cppblog.com/jinq0123/archive/2009/05/22/85378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>测试替身(Test Double)的定义</title><link>http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 18 May 2009 10:52:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/83306.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/83306.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/83306.html</trackback:ping><description><![CDATA[摘自：http://blog.vsharing.com/wooley/A801453.html<br><br>
<p>&nbsp;&nbsp;<strong>测试替身</strong>(Test Double)<strong>的定义</strong>  </p>
<p>&nbsp;</p>
<table class="MsoNormalTable" style="border: medium none ; width: 100%; border-collapse: collapse;" width="100%" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="border: 1pt dotted lightgrey; padding: 0.35pt;">
            <p><strong>测试替身型别</strong><strong></strong></p>
            </td>
            <td style="border-style: dotted dotted dotted none; border-color: lightgrey lightgrey lightgrey -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0.35pt;">
            <p><strong>描述</strong><strong></strong></p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Dummy</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>最简单、最原始的测试替身型别。Dummy 没有实作，最常用于需要参数值但不使用它的情况。Null 可视为是 Dummy，但真的 Dummy 是接口或基类的衍生，且完全不包含实作。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Stub</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>Dummy 的上一级，Stub 是接口或基类的最低限度实作。会传回 Void 的方法通常完全不包含实作，而会传回值的方法通常会传回硬式编码的值。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Spy</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>测试 Spy 类似 Stub，但除了提供客户端可叫用成员的实例，Spy 还会记录叫用了哪些成员，好让单元测试验证所叫用的成员是否符合预期。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Fake</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>Fake 包含更复杂的实作，通常涉及所继承型别之不同成员之间的互动。虽然不是完整的生产实作，但 Fake 与生产实作很相似，尽管它会采取一些快捷方式。</p>
            </td>
        </tr>
        <tr>
            <td style="border-style: none dotted dotted; border-color: -moz-use-text-color lightgrey lightgrey; border-width: medium 1pt 1pt; padding: 0.35pt;" valign="top">
            <p>Mock</p>
            </td>
            <td style="border-style: none dotted dotted none; border-color: -moz-use-text-color lightgrey lightgrey -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0.35pt;" valign="top">
            <p>Mock 是由 Mock 链接库动态建立 (其他通常是由测试开发人员使用程序代码来产生)。测试开发人员永远看不到实作接口或基类的实际程序代码，但是可以设定 Mock 以提供传回值、预期要叫用的特定成员...等等。视其中的设定而定，Mock 的行为可能会像 Dummy、Stub 或 Spy。</p>
            </td>
        </tr>
    </tbody>
</table>
&nbsp;
<br><br><img src ="http://www.cppblog.com/jinq0123/aggbug/83306.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-05-18 18:52 <a href="http://www.cppblog.com/jinq0123/archive/2009/05/18/83306.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost求数组的大小</title><link>http://www.cppblog.com/jinq0123/archive/2009/05/07/82145.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 07 May 2009 05:24:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/05/07/82145.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/82145.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/05/07/82145.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/82145.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/82145.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 求数组的大小，感觉boost库中应该有这个功能, 找了好长时间, 终于找到了.<br>原来是boost::extent, 属于boost::type_traits.&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/05/07/82145.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/82145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-05-07 13:24 <a href="http://www.cppblog.com/jinq0123/archive/2009/05/07/82145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>9C失去Wow代理权将促进中国Mangos的繁荣</title><link>http://www.cppblog.com/jinq0123/archive/2009/04/15/80040.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 15 Apr 2009 10:37:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/04/15/80040.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/80040.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/04/15/80040.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/80040.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/80040.html</trackback:ping><description><![CDATA[<p>9C失去Wow代理权将促进中国Mangos的繁荣</p>
<p>九城发布告全体员工书 确认续约魔兽无望, <br>详见: <a href="http://www.cnbeta.com/articles/81930.htm">http://www.cnbeta.com/articles/81930.htm</a></p>
<p>但是9C掌握了Wow的内幕技术, 这一优势如果投入到Mangos的开发中去, 那将是振奋人心的事情.<br></p>
<img src ="http://www.cppblog.com/jinq0123/aggbug/80040.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-04-15 18:37 <a href="http://www.cppblog.com/jinq0123/archive/2009/04/15/80040.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mangos的指令处理函数</title><link>http://www.cppblog.com/jinq0123/archive/2009/04/15/80037.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 15 Apr 2009 10:07:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/04/15/80037.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/80037.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/04/15/80037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/80037.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/80037.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: WorldSession中总共有300多个指令包处理函数, 以Handle开头, 无返回值, 参数为WorldPacket&. 例如: void HandleCharEnumOpcode(WorldPacket& recvPacket); 处理函数按功能分散在多个XXXHandler.cpp中实现. 例如: ArenaTeamHandler.cpp, AuctionHouseHandler.cpp. &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/04/15/80037.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/80037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-04-15 18:07 <a href="http://www.cppblog.com/jinq0123/archive/2009/04/15/80037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Wow, Mangos登录时的SRP6认证</title><link>http://www.cppblog.com/jinq0123/archive/2009/04/10/79490.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 10 Apr 2009 05:06:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/04/10/79490.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/79490.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/04/10/79490.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/79490.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/79490.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 以Mangos代码为参考, 解析SRP6的原理和实现. SRP全称Secure Remote Password（安全远程密码），是一个开源认证协议。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/04/10/79490.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/79490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-04-10 13:06 <a href="http://www.cppblog.com/jinq0123/archive/2009/04/10/79490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Mingw下bjam编译Luabind</title><link>http://www.cppblog.com/jinq0123/archive/2009/04/03/78770.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 03 Apr 2009 01:36:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/04/03/78770.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/78770.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/04/03/78770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/78770.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/78770.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: luabind-0.8只提供了bjam编译方式.<br>按手册上的要求,设置好BOOST_ROOT和LUA_PATH后, 运行bjam, 报错:&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/04/03/78770.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/78770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-04-03 09:36 <a href="http://www.cppblog.com/jinq0123/archive/2009/04/03/78770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用boost::spirit实现的表达式求值</title><link>http://www.cppblog.com/jinq0123/archive/2009/03/27/78047.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 27 Mar 2009 08:24:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/03/27/78047.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/78047.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/03/27/78047.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/78047.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/78047.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 用boost::spirit实现一个表达式求值看上去比较简单。我这个还有点问题，有空格时会解析失败，请大家看看是什么原因？&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/03/27/78047.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/78047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-03-27 16:24 <a href="http://www.cppblog.com/jinq0123/archive/2009/03/27/78047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内部推荐的职位</title><link>http://www.cppblog.com/jinq0123/archive/2009/03/17/76859.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 17 Mar 2009 05:48:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/03/17/76859.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/76859.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/03/17/76859.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/76859.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/76859.html</trackback:ping><description><![CDATA[<style>
st1\:*{behavior:url(#default#ieooui) }
</style><style>
<!--
/* Font Definitions */
@font-face
{font-family:System;
panose-1:0 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:宋体;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:"\@宋体";
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:"\@System";
panose-1:0 0 0 0 0 0 0 0 0 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
font-size:10.5pt;
font-family:"Times New Roman";}
a:link, span.MsoHyperlink
{color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal;
font-family:Arial;
color:windowtext;}
span.EmailStyle18
{mso-style-type:personal;
font-family:Arial;
color:navy;}
span.EmailStyle19
{mso-style-type:personal;
font-family:Arial;
color:navy;}
span.EmailStyle20
{mso-style-type:personal;
font-family:Arial;
color:navy;}
span.EmailStyle21
{mso-style-type:personal-reply;
font-family:Arial;
color:navy;}
@page Section1
{size:595.3pt 841.9pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
layout-grid:15.6pt;}
div.Section1
{page:Section1;}
/* List Definitions */
@list l0
{mso-list-id:1353914316;
mso-list-type:hybrid;
mso-list-template-ids:330341086 1178243674 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l0:level1
{mso-level-number-format:japanese-counting;
mso-level-text:%1、;
mso-level-tab-stop:21.0pt;
mso-level-number-position:left;
margin-left:21.0pt;
text-indent:-21.0pt;}
@list l0:level2
{mso-level-tab-stop:72.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level3
{mso-level-tab-stop:108.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level4
{mso-level-tab-stop:144.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level5
{mso-level-tab-stop:180.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level6
{mso-level-tab-stop:216.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level7
{mso-level-tab-stop:252.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level8
{mso-level-tab-stop:288.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
@list l0:level9
{mso-level-tab-stop:324.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;}
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
-->
</style>
<div class="Section1">
<p><font size="1" face="Arial">
<p><font>本次接受内部推荐的职位如下：</font></p>
<p><font>请将简历发送至邮箱jinq0123AT163.com。并在主题中标明：&#8220;内部推荐&#8221;以及所职位名称。</font></p>
<font>	</font></font></p>
<p><font size="2" face="Times New Roman">&nbsp;</font></p>
<p><font size="3" face="宋体">一、<font size="1" face="Times New Roman">&nbsp;&nbsp; </font></font><font size="3" face="宋体">产品专员（活动策划）</font><font size="3" face="宋体">&nbsp;</font><font size="3" face="System">
</font><font size="3" face="宋体">招聘人数：1人</font></p>
<p><font size="3" face="宋体">职位要求：<br>1、两年以上网络游戏运营活动策划工作经验<br>2、熟悉网络游戏产品及市场发展，热爱游戏事业，理解用户需求<br>3、出色的中文书面表达能力，要有一定的计划能力<br>4、具备激情、敏锐的观察力、分析能力和创意能力，思维严谨<br>5、出色的工作责任心、团队沟通能力和吃苦耐劳精神，能够适应加班<br>职位描述：<br>1、游戏线上、线下活动策划及方案拟定<br>2、与各相关部门有效的沟通，组织、协调和监督活动的执行情况<br>3、竞争对手相关活动收集与分析<br>4、配合市场人员完成的各种促销活动企划<br>5、竞争对手产品内容收集与分析</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">二</font><font size="3" face="宋体">&nbsp;</font><font size="3" face="System">
</font><font size="3" face="宋体">产品专员（新闻写作方向）</font><font size="3" face="宋体">&nbsp;&nbsp;&nbsp;&nbsp;</font><font size="3" face="宋体"> </font><font size="3" face="宋体">招聘人数：<font color="navy">1</font>人</font></p>
<p><font size="3" face="宋体">职位要求：<br>1、出众的文字功底、丰富想象力、缜密的逻辑思维能力<br>2、具备较强的传播价值分析能力和创意能力，有大局观以及对细节的把控能力<br>3、曾经在大型媒体上发表过作品者优先<br>4、具备互联网、媒体或游戏行业的从业背景，文科类优先<br>5、接触过多款网络游戏，并对专业游戏媒体有一定了解<br>6、性格开朗，良好的沟通能力、组织协调能力、团队合作精神，工作热情、主动，能承受较强的工作压力<font color="navy"></font></font></p>
<p><font size="3" face="宋体">7</font><font size="3" face="宋体">、英文良好</font></p>
<p><font size="3" face="宋体">职位描述：<br>1、参与新闻宣传计划的拟定工作<br>2、依照新闻宣传计划，与各相关部门有效的沟通，进行新闻策划及撰写<br>3、新闻稿件及各种软文稿件的撰写及组织</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">三、高级UI设计师</font></p>
<p><font size="3" face="宋体">招聘人数：2人</font></p>
<p><font size="3" face="宋体">岗位职责：<br><font color="#333333">1.</font><font color="#333333">参与FLASH社区和3D社区整体风格的设计。<br>2.完成社区界面风格的创意设计。</font></font></p>
<p><font size="3" face="宋体">岗位要求：<br>1.设计，美术相关专业毕业，两年以上UI设计或网页设计经验。<br>2.对用户体验有深入理解，并具有很好的沟通能力；<br>3.热爱游戏，思维活跃，富有团队精神，吃苦耐劳。<br>4.熟练使用Photoshop，
illustrator及Flash等绘图及制作软件；<br>5.有游戏UI设计经验者优先。</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">四</font><font size="3" face="宋体">&nbsp;&nbsp;</font><font size="3" face="System">
</font><font size="3" face="宋体">游戏3D组长</font></p>
<p><font size="3" face="宋体">工作职责：</font></p>
<p><font size="3" face="宋体">1</font><font size="3" face="宋体">、建设并领导美术团队开发高质量的网络游戏产品</font></p>
<p><font size="3" face="宋体">2</font><font size="3" face="宋体">、设定美术风格，保障游戏美术品质</font></p>
<p><font size="3" face="宋体">3</font><font size="3" face="宋体">、带领团队并参与制作，为成员提供艺术、技术上的指导</font></p>
<p><font size="3" face="宋体">4</font><font size="3" face="宋体">、建立高效的游戏美术开发流程，掌握管理开发进度</font></p>
<p><font size="3" face="宋体">5</font><font size="3" face="宋体">、认真审核部门内部员工的业绩、态度和潜力，并给予评定原由与报告</font></p>
<p><font size="3" face="宋体">任职要求：</font></p>
<p><font size="3" face="宋体">1</font><font size="3" face="宋体">、沟通能力强，善于发现和解决问题，积极主动，敢于担当责任。</font></p>
<p><font size="3" face="宋体">2</font><font size="3" face="宋体">、本科以上学历</font></p>
<p><font size="3" face="宋体">3</font><font size="3" face="宋体">、4年以上网络游戏开发经历</font></p>
<p><font size="3" face="宋体">4</font><font size="3" face="宋体">、完整指导至少2款网络游戏产品美术开发经历，并曾担任美术主管</font></p>
<p><font size="3" face="宋体">5</font><font size="3" face="宋体">、2年以上专业制作（原画，3d，2d，特效）经验</font></p>
<p><font size="3" face="宋体">6</font><font size="3" face="宋体">、了解并热爱网络游戏，热衷于游戏开发</font></p>
<p><font size="3" face="宋体">7</font><font size="3" face="宋体">、有次世代游戏开发管理和制作经验者优先</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">五</font><font size="3" face="宋体">&nbsp;</font><font size="3" face="System">
3D</font><font size="3" face="宋体">游戏地图编辑师</font></p>
<p><font size="3" face="宋体">工作职责：</font></p>
<p><font size="3" face="宋体">游戏场景地图编辑，制作地图，摆放物件等．</font></p>
<p><font size="3" face="宋体">任职要求：</font></p>
<p><font size="3" face="宋体">1</font><font size="3" face="宋体">、有着扎实的美术功底和悟性，有良好的三维空间思维和场景大局观</font></p>
<p><font size="3" face="宋体">2</font><font size="3" face="宋体">、热爱游戏，有很好的团队合作精神和交流协调能力</font></p>
<p><font size="3" face="宋体">3</font><font size="3" face="宋体">、能吃苦耐劳，工作态度严谨务实</font></p>
<p><font size="3" face="宋体">4</font><font size="3" face="宋体">、自学能力强，能快速掌握新的软件和应用</font></p>
<p><font size="3" face="宋体">5</font><font size="3" face="宋体">、有游戏3D场景人物制作经验者优先</font></p>
<p><font size="3" face="宋体">6</font><font size="3" face="宋体">、有1年以上3D游戏地图编辑经验者优先</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">六</font><font size="3" face="宋体">&nbsp;</font><font size="3" face="System">
</font><font size="3" face="宋体">角色原画、场景原画</font></p>
<p><font size="3" face="宋体">任职要求：</font></p>
<p><font size="3" face="宋体">1</font><font size="3" face="宋体">、两年以上游戏原画经验，独立设计能力突出。造型色彩基础扎实</font></p>
<p><font size="3" face="宋体">2</font><font size="3" face="宋体">、手绘和相应的软件应用要熟练</font></p>
<p><font size="3" face="宋体">3</font><font size="3" face="宋体">、有相应的工作上的作品可供参考</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">七</font><font size="3" face="宋体">&nbsp;</font><font size="3" face="System">
</font><font size="3" face="宋体">资深游戏策划</font></p>
<p><font size="3" face="宋体">岗位要求：</font><font size="3" face="宋体">&nbsp;</font><font size="3" face="System">
</font><font size="3" face="宋体"></font></p>
<p><font size="3" face="宋体">1</font><font size="3" face="宋体">、大专以上学历，熟练运用office系列软件；</font></p>
<p><font size="3" face="宋体">2</font><font size="3" face="宋体">、两年以上大型mmorpg策划经验，至少有一款参与制作的mmorpg上市运营；</font></p>
<p><font size="3" face="宋体">3</font><font size="3" face="宋体">、曾负责过大型mmorpg中社会关系设计并能提出完备的设计方案，对玩家交流需求有深入研究，善于设计玩家互动、社区建设；</font></p>
<p><font size="3" face="宋体">4</font><font size="3" face="宋体">、逻辑思维能力强，有创意；</font></p>
<p><font size="3" face="宋体">5</font><font size="3" face="宋体">、良好的沟通协调能力，团队意识强，能承受高强度工作压力。</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">八</font><font size="3" face="宋体">&nbsp;&nbsp;</font><font size="3" face="System"> Flash
</font><font size="3" face="宋体">开发工程师</font></p>
<p><font size="3" face="宋体">岗位要求：</font></p>
<p><font size="3" face="宋体">1</font><font size="3" face="宋体">、熟练使用flash或flex，精通AS3开发；</font></p>
<p><font size="3" face="宋体">2</font><font size="3" face="宋体">、精通oop，有良好的程序构架设计以及编程习惯；</font></p>
<p><font size="3" face="宋体">3</font><font size="3" face="宋体">、熟悉flash和后台数据通讯机制，了解flash与socket通信；</font></p>
<p><font size="3" face="宋体">4</font><font size="3" face="宋体">、工作认真负责，具有沟通及良好的团队合作精神；</font></p>
<p><font size="3" face="宋体">5</font><font size="3" face="宋体">、大专以上学历，有开发基于flash技术的大型2D社区的工作经历者优先考虑。</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font size="3" face="宋体">九</font><font size="3" face="宋体">&nbsp;&nbsp;</font><font size="3" face="System">
Flash/3D</font><font size="3" face="宋体">社区策划</font></p>
<p><font size="3" face="宋体">岗位要求：</font></p>
<p><font size="3" face="宋体">1</font><font size="3" face="宋体">、有两年以上的游戏或社区策划经验；</font></p>
<p><font size="3" face="宋体">2</font><font size="3" face="宋体">、对社区的研究和开发充满激情，对用户体验和产品细节方面有独特见解；</font></p>
<p><font size="3" face="宋体">3</font><font size="3" face="宋体">、曾负责过大型mmorpg中社会关系设计并能提出完备的设计方案，对玩家交流需求有深入研究者优先；</font></p>
<p><font size="3" face="宋体">4</font><font size="3" face="宋体">、逻辑思维能力强，创意丰富；</font></p>
<p><font size="3" face="宋体">5</font><font size="3" face="宋体">、语言表达及书面表达能力强；</font></p>
<p><font size="3" face="宋体">6</font><font size="3" face="宋体">、沟通协调能力强，富有团队精神，有敬业精神。</font></p>
<p><font size="3" face="宋体">&nbsp;</font></p>
<p><font color="black" size="2" face="宋体">巨人网络集团有限公司<br></font><font color="black" size="2" face="Arial">Giant
Interactive Group, Inc.</font><font color="black" size="2" face="宋体"><br></font><font color="black" size="2" face="宋体">中国上海市桂林路396号29号楼2楼 <br></font> 29th Building, 396
Guilin Road XuHui District, Shanghai, PRC 200233<font color="black" size="2" face="宋体"><br></font><font color="#333333" size="3" face="宋体"><br>&nbsp;</font></p>
<p><font size="1" face="Arial">&nbsp;</font></p>
</div>
<br>  <img src ="http://www.cppblog.com/jinq0123/aggbug/76859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-03-17 13:48 <a href="http://www.cppblog.com/jinq0123/archive/2009/03/17/76859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内部推荐的职位</title><link>http://www.cppblog.com/jinq0123/archive/2009/02/28/75148.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Sat, 28 Feb 2009 05:34:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/02/28/75148.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/75148.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/02/28/75148.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/75148.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/75148.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 请将简历发送至邮箱。并在主题中标明：“内部推荐”以及所职位名称。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/02/28/75148.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/75148.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-02-28 13:34 <a href="http://www.cppblog.com/jinq0123/archive/2009/02/28/75148.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C调用lua脚本的效率测试</title><link>http://www.cppblog.com/jinq0123/archive/2009/02/17/73998.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 17 Feb 2009 01:32:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/02/17/73998.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/73998.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/02/17/73998.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/73998.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/73998.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 以下代码以C语言为基准，测试了C调用Lua循环和循环调用Lua的效率。结论是不要频繁地穿越C/Lua边界. &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2009/02/17/73998.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/73998.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-02-17 09:32 <a href="http://www.cppblog.com/jinq0123/archive/2009/02/17/73998.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>