﻿<?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++博客-The Welkin of FlyingBear-随笔分类-C++</title><link>http://www.cppblog.com/fbitw/category/3634.html</link><description>Programming for Fun</description><language>zh-cn</language><lastBuildDate>Wed, 21 May 2008 08:54:00 GMT</lastBuildDate><pubDate>Wed, 21 May 2008 08:54:00 GMT</pubDate><ttl>60</ttl><item><title>个人网站进行中...</title><link>http://www.cppblog.com/fbitw/archive/2007/06/11/26087.html</link><dc:creator>FlyingBear</dc:creator><author>FlyingBear</author><pubDate>Mon, 11 Jun 2007 11:21:00 GMT</pubDate><guid>http://www.cppblog.com/fbitw/archive/2007/06/11/26087.html</guid><wfw:comment>http://www.cppblog.com/fbitw/comments/26087.html</wfw:comment><comments>http://www.cppblog.com/fbitw/archive/2007/06/11/26087.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/fbitw/comments/commentRss/26087.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/fbitw/services/trackbacks/26087.html</trackback:ping><description><![CDATA[<p>看了一些很酷的个人网站,像曾经的燕尘小筑,感觉以后咱做这一行的,肯定是需要这样一个平台来展示自己的,做这个是早晚的事,试了一些第三方的BLOG,比如这个,总觉得不是自己的东西,用起来就是不爽,所以还是得自己弄一个,不过因为是代表个人的终极网站了,所以也不急,现在完成度大概只有1%&nbsp; :)<br><br>另外,俞益州老师来我们学校讲学的时候,我看到他也没做什么准备,电脑上有一个demo文件夹,里面放了各种PPT和演示用的视频,随手拿来就讲,这个很好,也要学,还有什么个人简历,创业计划什么的,能写好,整理好的,都放在一起,什么时候见到个志同道合的,立马拿出来介绍.哈哈<br><br>个人网站的设计目标,首先必须要HTML与PHP分离,这可以方便UI设计师的工作,不用去看超级ugly的PHP代码,这可以靠smarty模板引擎做到,小试了一下,用起来还是很直观的:)<br><br>另外,最好还需要PHP与逻辑层分离,这个没有仔细研究过,应该是要用一些框架,像Zend Framework,CakePHP什么的,口碑还不错.突然看到两张图,讲怎么开发好的PHP项目的,看过以后豁然开朗,share一下.<br>(点击看大图)<br><br><br><br><br><br></p>
<p><a href="http://www.cppblog.com/images/cppblog_com/fbitw/4142/o_PHP1.gif"><img src="http://www.cppblog.com/images/cppblog_com/fbitw/4142/r_PHP1.gif"></img></a> <a href="http://www.cppblog.com/images/cppblog_com/fbitw/4142/o_PHP2.gif"><img src="http://www.cppblog.com/images/cppblog_com/fbitw/4142/r_PHP2.gif"></img></a> </p>
<img src ="http://www.cppblog.com/fbitw/aggbug/26087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/fbitw/" target="_blank">FlyingBear</a> 2007-06-11 19:21 <a href="http://www.cppblog.com/fbitw/archive/2007/06/11/26087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>发现自己土了</title><link>http://www.cppblog.com/fbitw/archive/2007/04/29/23215.html</link><dc:creator>FlyingBear</dc:creator><author>FlyingBear</author><pubDate>Sun, 29 Apr 2007 14:21:00 GMT</pubDate><guid>http://www.cppblog.com/fbitw/archive/2007/04/29/23215.html</guid><wfw:comment>http://www.cppblog.com/fbitw/comments/23215.html</wfw:comment><comments>http://www.cppblog.com/fbitw/archive/2007/04/29/23215.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cppblog.com/fbitw/comments/commentRss/23215.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/fbitw/services/trackbacks/23215.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 写完上一篇日志"静态回调函数到成员函数的转换", 问了一下石教主有什么看法, 结果不问不知道, 一问才发现自己彻底土了, 这个问题用boost::bind可以解决得这么好, 调用的函数参数个数都可以没有限制... 唉, 以后还是要好好学习ps. 不过不知道这个方法运行效率怎么样, 还要继续试验// 下面的内容于2007年5月4日改成最后用的版本了实现的功能:(1) 用于把非多线程的代码改成多线程(...&nbsp;&nbsp;<a href='http://www.cppblog.com/fbitw/archive/2007/04/29/23215.html'>阅读全文</a><img src ="http://www.cppblog.com/fbitw/aggbug/23215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/fbitw/" target="_blank">FlyingBear</a> 2007-04-29 22:21 <a href="http://www.cppblog.com/fbitw/archive/2007/04/29/23215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>静态回调函数到成员函数的转换</title><link>http://www.cppblog.com/fbitw/archive/2007/04/21/22490.html</link><dc:creator>FlyingBear</dc:creator><author>FlyingBear</author><pubDate>Sat, 21 Apr 2007 06:23:00 GMT</pubDate><guid>http://www.cppblog.com/fbitw/archive/2007/04/21/22490.html</guid><wfw:comment>http://www.cppblog.com/fbitw/comments/22490.html</wfw:comment><comments>http://www.cppblog.com/fbitw/archive/2007/04/21/22490.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/fbitw/comments/commentRss/22490.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/fbitw/services/trackbacks/22490.html</trackback:ping><description><![CDATA[<p>经常会有一些类库或者API要求传入一个等效于全局函数的函数指针作为回调函数,一个典型的例子是Win32的建立线程<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID&nbsp;lpParameter);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>HANDLE&nbsp;hThread&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CreateThread(NULL,&nbsp;NULL,&nbsp;ThreadFunc,&nbsp;NULL,&nbsp;NULL,&nbsp;NULL);</span></div>
<br>然而,对于我们自己的工程来说,更希望作为线程的函数是某个类的成员函数,所以需要在这个全局函数里调用类的成员函数,像这样<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">ClassA&nbsp;a;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID&nbsp;lpParameter)<br><img id=Codehighlighter1_54_106_Open_Image onclick="this.style.display='none'; Codehighlighter1_54_106_Open_Text.style.display='none'; Codehighlighter1_54_106_Closed_Image.style.display='inline'; Codehighlighter1_54_106_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_54_106_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_54_106_Closed_Text.style.display='none'; Codehighlighter1_54_106_Open_Image.style.display='inline'; Codehighlighter1_54_106_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_54_106_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_54_106_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;((ClassA</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)&nbsp;lpParameter)</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">SomeMethod();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>HANDLE&nbsp;hThread&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CreateThread(NULL,&nbsp;NULL,&nbsp;ThreadFunc,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a,&nbsp;NULL,&nbsp;NULL);</span></div>
<br>DirectX SDK以前就用过这样的方法,也可以把全局函数换成类的静态成员函数,<br><br>但这样用起来很麻烦,每次都要写一个全局函数的Shell,所以这里,我们想办法把这个过程自动化起来.<br><br>问题的关键是在静态或者全局的函数里,只能得到一个传进来的参数,而要指定一个成员函数,需要一个this指针,以及一个指向类成员函数的指针,这两个参数没法全部通过lpParameter传进来,除非lpParameter传一个额外写的结构的指针,这个结构里包含this指针和成员函数指针,但这样需要临时分配一个对象,不方便,所以只能牺牲运行时代码的简洁性,用模板参数来传成员函数指针的值,而lpParameter只负责传this,但是另一个问题是用模板参数来传具体的值时,必须类型已知,像下面的代码是不能运作的<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;T,&nbsp;PtrToMemThreadFun&nbsp;pFunc</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID&nbsp;lpParameter)<br><img id=Codehighlighter1_90_131_Open_Image onclick="this.style.display='none'; Codehighlighter1_90_131_Open_Text.style.display='none'; Codehighlighter1_90_131_Closed_Image.style.display='inline'; Codehighlighter1_90_131_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_90_131_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_90_131_Closed_Text.style.display='none'; Codehighlighter1_90_131_Open_Image.style.display='inline'; Codehighlighter1_90_131_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_90_131_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_90_131_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;(((T</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)lpParameter)</span><span style="COLOR: #000000">-&gt;*</span><span style="COLOR: #000000">pFunc)();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>CreateThread(NULL,&nbsp;NULL,&nbsp;ThreadFunc</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ClassA,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">ClassA::SomeMethod</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a,&nbsp;NULL,&nbsp;NULL);</span></div>
<br>因为PtrToMemThreadFun的类型不定,所以只能先外包一层模板类来确定类型,像这样<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">typename&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;ThreadFac<br><img id=Codehighlighter1_38_248_Open_Image onclick="this.style.display='none'; Codehighlighter1_38_248_Open_Text.style.display='none'; Codehighlighter1_38_248_Closed_Image.style.display='inline'; Codehighlighter1_38_248_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_38_248_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_38_248_Closed_Text.style.display='none'; Codehighlighter1_38_248_Open_Image.style.display='inline'; Codehighlighter1_38_248_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_38_248_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_38_248_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;DWORD&nbsp;(T::</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">PtrToMemThreadFunc)();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;T&nbsp;ClassType;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;template</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">PtrToMemThreadFunc&nbsp;pFunc</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;DWORD&nbsp;WINAPI&nbsp;ThreadFunc(LPVOID&nbsp;lpParameter)<br><img id=Codehighlighter1_195_246_Open_Image onclick="this.style.display='none'; Codehighlighter1_195_246_Open_Text.style.display='none'; Codehighlighter1_195_246_Closed_Image.style.display='inline'; Codehighlighter1_195_246_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_195_246_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_195_246_Closed_Text.style.display='none'; Codehighlighter1_195_246_Open_Image.style.display='inline'; Codehighlighter1_195_246_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_195_246_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_195_246_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;(((ClassType</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">)lpParameter)</span><span style="COLOR: #000000">-&gt;*</span><span style="COLOR: #000000">pFunc)();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>调用时,就可以自动化了<br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Globally</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">CreateThread(NULL,&nbsp;NULL,&nbsp;ThreadFac</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ClassA</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::ThreadFunc</span><span style="COLOR: #000000">&lt;&amp;</span><span style="COLOR: #000000">ClassA::SomeMethod</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">a,&nbsp;NULL,&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;In&nbsp;methods&nbsp;of&nbsp;ClassA</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">CreateThread(NULL,&nbsp;NULL,&nbsp;ThreadFac</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">ClassA</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">::ThreadFunc</span><span style="COLOR: #000000">&lt;&amp;</span><span style="COLOR: #000000">ClassA::SomeMethod</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">,&nbsp;NULL,&nbsp;NULL);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<br>
<img src ="http://www.cppblog.com/fbitw/aggbug/22490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/fbitw/" target="_blank">FlyingBear</a> 2007-04-21 14:23 <a href="http://www.cppblog.com/fbitw/archive/2007/04/21/22490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>日志系统的几则妙用</title><link>http://www.cppblog.com/fbitw/archive/2007/02/17/18845.html</link><dc:creator>FlyingBear</dc:creator><author>FlyingBear</author><pubDate>Sat, 17 Feb 2007 14:19:00 GMT</pubDate><guid>http://www.cppblog.com/fbitw/archive/2007/02/17/18845.html</guid><wfw:comment>http://www.cppblog.com/fbitw/comments/18845.html</wfw:comment><comments>http://www.cppblog.com/fbitw/archive/2007/02/17/18845.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/fbitw/comments/commentRss/18845.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/fbitw/services/trackbacks/18845.html</trackback:ping><description><![CDATA[
		<p>1.HTML日志<br />对日志系统的文本输出部分稍做修改，每一行前加&lt;P&gt;，后加&lt;/P&gt;，输出结果就成了一个可浏览的HTML，然后，凡HTML能包括的东西，都能让日志系统去LOG，做成一个图文并茂的日志，这对于科研应用来说有很重要的意义，因为经常生成临时的图像，或者需要对某个数据结果可视化，这时候如果只要一个简单的语句如</p>
		<p>LogManager::getSingleton().logImage(someImage)</p>
		<p>或者用宏进一步简化</p>
		<p>LOG(someImage)</p>
		<p>就完成了临时图像的自动命名，并保存，然后添加到日志里，那将是很有吸引力的，生成的日志有点像一个Report，可以直接发给Boss看，当工作汇报 :)</p>
		<p>为了对LOG进去的媒体内容有一定的处理，如显示的时候缩放到合适的大小等，需要在日志文件的头部加入一些Javascript的代码，这需要日志系统的支持，能在开始记日志的时候判断当前日志文件是否已经存在，只在不存在的时候才加入相应的页首代码。</p>
		<p>当然，更进一步可以做成结构化的日志，这个还有待尝试</p>
		<p>2.Comment - Report 机制<br />如果写的程序经常发生变化，那么时间长了以后，日志下来的数据是由什么样的代码产生的，就会不记得了，导致大量的数据没有办法分析，这里我用这样的办法</p>
		<p>在产生数据的代码附近用这样一个语句</p>
		<p>COMMENT(subject)</p>
		<p>subject是一个字符串值，表示这一部分数据的主题，这个宏展开以后是这样的</p>
		<p>LogManager::getSingleton().addComment(subject, __FILE__, __LINE__);</p>
		<p>这个函数在HTML的日志文件里新增一行，并生成一个超链接目的地，同时LogManager记下这个(string, string, int)组合</p>
		<p>在LogManager被关闭的时候，会对所有的 Comment根据 Subject归类，生成一个Techinical Report，像下面这样</p>
		<p>Tech Report:<br />---------------------------------------------------------<br />* SubjectA:<br />Comment1 - FileName - LineNo<br />Code Segment of Comment1<br />Comment2 - FileName - LineNo<br />Code Segment of Comment2<br />...<br />* SubjectB:<br />...<br />---------------------------------------------------------<br />同一个Subject可以对应多个代码段，单击Report里的 Comment 可以跳转到先前 Comment生成的超链接日的地。<br />Code Segment由LogManager根据__FILE__和__LINE__从文件里读取</p>
		<p>3.变量记录宏</p>
		<p>一些有用的宏对记录变量很有好处<br />#define LOGVAR(x) ToolLib::LOG(#x + std::string(" = ") + TOSTR(x))<br />#define LOGARR(x, i) ToolLib::LOG(#x + std::string("[") + TOSTR(i) + "] = " + TOSTR(x[i]))</p>
		<p>用了这些宏就可以随处记录变量的值</p>
		<p>4.直接数据记录</p>
		<p>LogManager需要有一个方法给出所用的文件对象,如 ofstream或 FILE*，这样，对于大数据量的日志，比如几千个int值，可以用这个文件对象直接输入，而省去每一行记录日期时间的麻烦</p>
		<p>5.替换stdout或cout</p>
		<p>经常有些第三方的库用printf或者cout来输出信息，需要想办法把这些内容也catch到自己的日志系统里，对于printf模式的，可以用</p>
		<p>FILE* fid = fopen();<br />*stdout = *fid;</p>
		<p>来实现，而对于cout型的，不好办，可以自己写一个新的ostream子类，然后用宏把cout重新define一下，设成自己的ostream，并重写一下sync函数来capture输出。</p>
<img src ="http://www.cppblog.com/fbitw/aggbug/18845.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/fbitw/" target="_blank">FlyingBear</a> 2007-02-17 22:19 <a href="http://www.cppblog.com/fbitw/archive/2007/02/17/18845.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost::Serialization试用手记</title><link>http://www.cppblog.com/fbitw/archive/2007/02/16/18818.html</link><dc:creator>FlyingBear</dc:creator><author>FlyingBear</author><pubDate>Thu, 15 Feb 2007 17:06:00 GMT</pubDate><guid>http://www.cppblog.com/fbitw/archive/2007/02/16/18818.html</guid><wfw:comment>http://www.cppblog.com/fbitw/comments/18818.html</wfw:comment><comments>http://www.cppblog.com/fbitw/archive/2007/02/16/18818.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cppblog.com/fbitw/comments/commentRss/18818.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/fbitw/services/trackbacks/18818.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 对于核心数据相对比较集中的应用程序来说，serialization机制可以直接充当文档保存与打开功能的实现工具，这也是很多成熟的应用程序framework都提供serialization支持的原因但是个人认为，serialization最精彩的用处在于保存现场，比如在探索性的科研应用程序开发过程中，很可能一部分算法已经固定下来，其余的有待进一步探索，而确定下来的部分有可能十分time consum...&nbsp;&nbsp;<a href='http://www.cppblog.com/fbitw/archive/2007/02/16/18818.html'>阅读全文</a><img src ="http://www.cppblog.com/fbitw/aggbug/18818.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/fbitw/" target="_blank">FlyingBear</a> 2007-02-16 01:06 <a href="http://www.cppblog.com/fbitw/archive/2007/02/16/18818.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>