用户操作
[留言]  [发消息]  [加为好友] 
订阅我的博客
XML聚合    FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
pongba的公告
除非特别声明,本站采用<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/" rel="license"><img width="16" height="16" border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_o_cclogo.gif" alt="Creative Commons License"/></a>许可。转载请保留作者、出处。非商业。 <br/> <h3>重要公告</h3> <div style="background:#000000;color:#ffffff;">本博客已经迁移至 http://mindhacks.cn ,此处保留作为镜像,但不保证一定同步更新所有内容。原订阅 http://blog.csdn.net/pongba/rss.aspx (原始 Feed) 的朋友请转为订阅永久 feed : http://mindhacks.cn/feed/</div> <h3>关于</h3> 我经常在 @<a href="https://groups.google.com/group/pongba" target="_blank">TopLanguage</a> | @<a href="https://twitter.com/pongba" target="_blank">Twitter</a> | @<a href="http://www.douban.com/people/pongba/" target="_blank">Douban</a> <br/><br/> <style type="text/css"> #accordionmenu ul{ list-style-type: none; } #accordionmenu li{ list-style-type: none; padding: 0px; } #accordionmenu ul, #accordionmenu ul ul { list-style: none; margin: 0; padding: 0; } #accordionmenu ul li { display: inline; } #accordionmenu ul a { display: block; text-decoration: none; } #accordionmenu ul li ul li{ vertical-align: bottom; } #accordionmenu ul li a { background: #333; color: #fff; padding: 0.5em; } #accordionmenu ul li a:hover { background: #000; } #accordionmenu ul li a, #accordionmenu ul li a:hover { border-bottom: 1px dotted #C0C0C0; } #accordionmenu ul li ul li a { background: #ccc; color: #000; padding-left: 20px; } #accordionmenu ul li ul li a:hover { background: #aaa; border-left: 5px #000 solid; padding-left: 15px; } #accordionmenu h3 { font-weight: bold; text-align: center; font-size: 14pt; border-bottom: none; } #accordionmenu h1 { font-size: 14px; font-weight: bold; text-align: center; } #accordionmenu p { text-align: right; } .sharing { border:1px dotted #AAAAAA; padding:10px; } </style> <div id="accordionmenu"> <h3>《C++的罗浮宫》5年选集</h3> <p>——知识分享是最大的复用</p> 下载地址:<a href="http://download.csdn.net/source/630320" target="_blank">csdn资源频道</a>|<a href="http://www.mediafire.com/?r9y9aynxy84" target="_blank">mediafire</a> <ul> <li> <a target="_blank" href="http://del.icio.us/pongbablog/machine-learning">机器学习与人工智能</a> <ul> <li><a href="http://blog.csdn.net/pongba/archive/2008/09/21/2958094.aspx">数学之美番外篇:平凡而又神奇的贝叶斯方法</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/09/11/2915005.aspx">机器学习与人工智能学习资源导引</a></li> </ul> </li> <li> <a target="_blank" href="http://del.icio.us/pongbablog/essay">学习与思考</a> <ul> <li><a href="http://blog.csdn.net/pongba/archive/2008/12/18/3549560.aspx">如何清晰地思考:近一年来业余阅读的关于思维方面的知识结构整理(附大幅思维导图)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2009/01/14/3776586.aspx">什么是你的不可替代性和核心竞争力</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2009/01/16/3796771.aspx">锤子和钉子</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2009/01/18/3829054.aspx">逃出你的肖申克(一):一定要亲身经历了之后才能明白?</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/07/08/2625115.aspx">一直以来伴随我的一些学习习惯(part1)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/07/20/2681668.aspx">一直以来伴随我的一些学习习惯(part2)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/09/17/2942482.aspx">一直以来伴随我的一些学习习惯(part3)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/12/05/3456240.aspx">一直以来伴随我的一些学习习惯(part4)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/10/29/3176250.aspx">方法论、方法论——程序员的阿喀琉斯之踵</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/07/07/2622713.aspx">知其所以然地学习(以算法学习为例)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/04/08/2260812.aspx">阅读与思考</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/03/03/2143245.aspx">Failing To See the Big Picture - Mistakes we make when learning programming</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/02/25/2118907.aspx">你的技术之路</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/01/04/2025830.aspx">鱼是最后一个看到水的</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/08/10/1736333.aspx">玩的岁月</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/06/24/1664597.aspx">我不想与我不能</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/05/24/1624382.aspx">学习密度与专注力</a></li> </ul> </li> <li> <a target="_blank" href="http://del.icio.us/pongbablog/problem-solving">解题与思维</a> <ul> <li><a href="http://blog.csdn.net/pongba/archive/2008/04/18/2302905.aspx">跟波利亚学解题(rev#3)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/06/05/2513263.aspx">学习与记忆</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/05/07/2412144.aspx">解题思维杂感三则</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/06/05/2513247.aspx">动态规划与排列组合</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/04/09/2270171.aspx">今天我们思考</a></li> </ul> </li> <li> <a target="_blank" href="http://del.icio.us/pongbablog/math">数学与计算理论</a> <ul> <li><a href="http://blog.csdn.net/pongba/archive/2006/10/15/1336028.aspx">康托尔、哥德尔、图灵——永恒的金色对角线(rev#2)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/12/02/1912466.aspx">数学之美番外篇:进化论中的概率论</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/06/13/2544933.aspx">数学之美番外篇:快排为什么那样快</a></li> </ul> </li> <li> <a target="_blank" href="http://del.icio.us/pongbablog/cplusplus">C++与技术</a> <ul> <li><a href="http://blog.csdn.net/pongba/archive/2007/09/11/1780545.aspx">为什么C++</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/12/04/1916385.aspx">为什么C++(C++之父的观点)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/12/11/1930150.aspx">学习C++:实践者的方法</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/05/16/1611593.aspx">你应当如何学习C++(以及编程)(rev#1)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/01/10/2034207.aspx">C++之父元旦专访(8+13个问题,关于C++的学习使用和未来)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/08/08/1732055.aspx">争论C++前你应当知道什么(rev#1)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/10/08/1815742.aspx">错误处理:为何、何时、如何(rev#2)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2006/01/26/588638.aspx">锁无关的数据结构</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2006/01/29/589864.aspx">锁无关的数据结构与Hazard指针</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/06/13/2544894.aspx">泛型编程:源起、实现与意义</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/07/29/1715263.aspx">Generic Programming - What are you, anyway?</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2004/09/01/90642.aspx">深度探索元函数</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2003/10/24/19130.aspx">为什么C++编译器不能支持对模板的分离式编译</a></li> </ul> </li> <li> <a href="http://blog.csdn.net/pongba/articles/1561194.aspx">《C++0x漫谈》系列</a> <ul> <li><a href="http://blog.csdn.net/pongba/archive/2007/08/04/1726031.aspx">《C++0x漫谈》之:Concept! Concept!</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/09/10/1778748.aspx">《C++0x漫谈》之:瘦身前后——兼谈语言进化</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/09/07/1776255.aspx">《C++0x漫谈》之:Auto的故事</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/07/10/1684519.aspx">《C++0x漫谈》之:Move语意与完美转发(上)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/07/18/1697636.aspx">《C++0x漫谈》之:Move语意与完美转发(下)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/06/20/1659952.aspx">《C++0x漫谈》之:多线程内存模型</a></li> </ul> </li> <li> <a href="http://blog.csdn.net/pongba/articles/1561110.aspx">《Boost源码剖析》系列</a> <ul> <li><a href="http://blog.csdn.net/pongba/archive/2007/04/11/1561006.aspx">《Boost源码剖析》之:多重回调机制signal(上)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/04/11/1561083.aspx">《Boost源码剖析》之:多重回调机制signal(下)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/04/11/1560773.aspx">《Boost源码剖析》之:泛型回调function(rev#3)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/04/11/1560754.aspx">《Boost源码剖析》之:Tuple Types(rev#2)</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/04/11/1560738.aspx">《Boost源码剖析》之:泛型多维数组multi_array</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2004/08/24/82811.aspx">《Boost源码剖析》之:泛型指针any(rev#2)</a></li> </ul> </li> <li> <a target="_blank" href="http://del.icio.us/pongbablog/essay">其它</a> <ul> <li><a href="http://del.icio.us/pongbablog/%E5%8F%A4%E9%BE%99">读古龙的岁月</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/10/07/1813553.aspx">我们为什么这么容易受骗?</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2007/04/26/1586144.aspx">Blog外挂:妙用del.icio.us实现“站内相关文章”</a></li> <li><a href="http://blog.csdn.net/pongba/archive/2008/03/12/2172677.aspx">找啊找啊找朋友</a></li> </ul> </li> <li> <a href="http://blog.csdn.net/pongba/MyArticles.aspx">所有文章</a> </li> </ul> </div> <br/> <style type="text/css"> .delicious-posts ul {list-style-type:none; margin: 0 0 1em 0; padding: 0 } .delicious-extended{margin:0;padding:0 0 0.25em 0} .module-list-item .delicious-posts ul{margin:0;padding:0} .module-list-item .delicious-posts h2, .module-list-item .delicious-posts li:first-child{margin-top:0} </style> <h3>讨论问题请到<a href="http://groups.google.com/group/pongba">TopLanguage</a>综合技术讨论组</h3> <center><a href="http://groups.google.com/group/pongba"><img border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_01-sm-c.gif" alt="TopLanguage"></img></a></center> <br/> <h3>精彩言论@TopLanguage</h3> <div id="toplang_comments" class="sharing"> </div> <br/> <h3>pongba的共享阅读<a href="http://delicious.com/pongba" target="_blank">@Delicious</a></h3> <div id="delicious_shared_reading" class="sharing"> </div> <br/> <h3>pongba<a href="http://twitter.com/pongba" target="_blank">@Twitter</a></h3> <div id = "twitter_update_list" class="sharing"> </div> <script type="text/javascript"> function twitterCallback2(C){var A=[];for(var D=0;D<C.length;D++){var E=C[D].user.screen_name;var B=C[D].text.replace(/((https?|s?ftp|ssh)\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!])/g,function(F){return'<a href="'+F+'">'+F+"</a>"}).replace(/\B@([_a-z0-9]+)/ig,function(F){return F.charAt(0)+'<a href="http://www.twitter.com/'+F.substring(1)+'">'+F.substring(1)+"</a>"});A.push("<li><span>"+B+'</span> <a style="font-size:85%" href="http://twitter.com/'+E+"/statuses/"+C[D].id+'">'+relative_time(C[D].created_at)+"</a></li>")}document.getElementById("twitter_update_list").innerHTML=A.join("")}function relative_time(C){var B=C.split(" ");C=B[1]+" "+B[2]+", "+B[5]+" "+B[3];var A=Date.parse(C);var D=(arguments.length>1)?arguments[1]:new Date();var E=parseInt((D.getTime()-A)/1000);E=E+(D.getTimezoneOffset()*60);if(E<60){return"less than a minute ago"}else{if(E<120){return"about a minute ago"}else{if(E<(60*60)){return(parseInt(E/60)).toString()+" minutes ago"}else{if(E<(120*60)){return"about an hour ago"}else{if(E<(24*60*60)){return"about "+(parseInt(E/3600)).toString()+" hours ago"}else{if(E<(48*60*60)){return"1 day ago"}else{return(parseInt(E/86400)).toString()+" days ago"}}}}}}}; </script> <br/> <h3>pongba在读<a href="http://www.douban.com/people/pongba/" target="_blank">@豆瓣</a></h3> <script type="text/javascript" src="http://www.douban.com/service/badge/pongba/?show=dolist&amp;select=favorite&amp;n=9&amp;columns=3&amp;cat=book" ></script> <br/> <h3>gtalk/msn(邮件请发送到gmail邮箱)</h3> <a href="mailto:pongba@gmail.com"> <img border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_gmail.gif" alt="pongba@gmail.com"></img> </a> <br/> <a href = "mailto:pp_liu@msn.com"> <img border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_msn.gif" alt="pp_liu@msn.com"></img> </a> <br/> <h3>搜索(不要回车,点击Go)</h3> <script language="javascript"> function search () { var wd=document.getElementsByName("q")[0].value; var link="http://www.baidu.com/s?ie=utf-8&tn=baidulocal&cl=3&ct=2097152&si=blog.csdn.net%2Fpongba" + "&wd=" + wd ; window.open(link); } </script> <input type="text" onkeydown="javascript:var kCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode; if (kCode == 13){search();}" name="q"/> <input type="button" onclick="javascript:search()" value="Go"/> <br/> <h3>pongba翻译的</h3> <br/> <center> <a href="http://blog.csdn.net/pongba/archive/2007/12/03/1914425.aspx" target="_blank"><img border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_bc_small.JPG"></img></a> </center> <br/> <center> <a href="http://blog.csdn.net/pongba/archive/2007/03/09/1525361.aspx" target="_blank"><img border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_wewlc_small.jpg"></img></a> </center> <br/> <center> <a href="http://blog.csdn.net/pongba/archive/2005/11/22/534336.aspx" target="_blank"><img border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_ecs_small.JPG"></img></a> </center> <br/> <center> <a href="http://blog.csdn.net/pongba/archive/2005/08/15/455350.aspx" target="_blank"><img border="0" src="http://p.blog.csdn.net/images/p_blog_csdn_net/pongba/186037/o_ic_small.JPG"></img></a> </center> <script type="text/javascript"> (function(){ var toplang = document.createElement('div'); toplang.setAttribute('id', 'toplang'); toplang.setAttribute('style', 'float:right; margin:0pt 1em; position:absolute; right:2%; top:15px;') var a1 = document.createElement('a'); a1.setAttribute('href', 'http://groups.google.com/group/pongba'); a1.setAttribute('target', '_blank'); a1.setAttribute('title', 'TopLanguage'); a1.setAttribute('style', 'text-decoration: underline;'); a1.appendChild(document.createTextNode('TopLanguage讨论组')); toplang.appendChild(a1); toplang.appendChild(document.createTextNode(' | ')); a1 = document.createElement('a'); a1.setAttribute('href', 'http://groups.google.com/group/pongba/web/toplanguage-subscription-howto'); a1.setAttribute('target', '_blank'); a1.setAttribute('title', '加入TopLanguage'); a1.setAttribute('style', 'text-decoration: underline;'); a1.appendChild(document.createTextNode('加入')); toplang.appendChild(a1); var header = document.getElementById('csdnblog_header'); if(header) { header.appendChild(toplang); } })(); </script> <script type="text/javascript"> /* test if _item_ is in _set_ */ function IsIn(item, set) { for(var i = 0; i < set.length; ++i){ if(set[i]&&(item == set[i]))return true; } return false; } /* get the link to the current page, strip out the # part if the page is opened through a comment link */ function GetThisURL() { var thisURL = document.URL; var end = thisURL.indexOf('#'); if(end != -1){ thisURL = thisURL.slice(0, end); } return thisURL; } /* select from _set_ all the elements that don't exist in _filter_ */ function Unique(set, filter) { var newSet = new Array(); for(var i = 0; i < set.length; i++){ if(!IsIn(set[i], filter)) newSet.push(set[i]); } return newSet; } /* randomly select _num_ items from _set_ */ function RandomSelection(set, num) { var selected = new Array(); var positiveSelecting = (num <= set.length/2); var ajustedNum = (positiveSelecting ? num : (set.length - num)); for(var n = 0; n < ajustedNum;){ var randIdx = Math.floor(Math.random()*(set.length)); if(!IsIn(set[randIdx], selected)){ selected.push(set[randIdx]); n++; } } if(!positiveSelecting){ selected = Unique(set, selected); } return selected; } function getElements(classname, tagname, root) { // If no root was specified, use the entire document // If a string was specified, look it up if (!root) root = document; else if (typeof root == "string") root = document.getElementById(root); // if no tagname was specified, use all tags if (!tagname) tagname = "15-"; // Find all descendants of the specified root with the specified tagname var all = root.getElementsByTagName(tagname); // If no classname was specified, we return all tags if (!classname) return all; // Otherwise, we filter the element by classname var elements = []; // Start with an empty array for(var i = 0; i < all.length; i++) { var element = all[i]; if (isMember(element, classname)) // isMember() is defined below elements.push(element); // Add class members to our array } // Note that we always return an array, even if it is empty return elements; // Determine whether the specified element is a member of the specified // class. This function is optimized for the common case in which the // className property contains only a single classname. But it also // handles the case in which it is a list of whitespace-separated classes. function isMember(element, classname) { var classes = element.className; // Get the list of classes if (!classes) return false; // No classes defined if (classes == classname) return true; // Exact match // We didn't match exactly, so if there is no whitespace, then // this element is not a member of the class var whitespace = /\s+/; if (!whitespace.test(classes)) return false; // If we get here, the element is a member of more than one class and // we've got to check them individually. var c = classes.split(whitespace); // Split with whitespace delimiter for(var i = 0; i < c.length; i++) { // Loop through classes if (c[i] == classname) return true; // and check for matches } return false; // None of the classes matched } } var HTTP = {}; HTTP._factories = [ function() { return new XMLHttpRequest(); }, function() { return new ActiveXObject("Msxml2.XMLHTTP"); }, function() { return new ActiveXObject("Microsoft.XMLHTTP"); } ]; HTTP._factory = null; HTTP.newRequest = function() { if (HTTP._factory != null) return HTTP._factory(); for(var i = 0; i < HTTP._factories.length; i++) { try { var factory = HTTP._factories[i]; var request = factory(); if (request != null) { HTTP._factory = factory; return request; } } catch(e) { continue; } } HTTP._factory = function() { throw new Error("XMLHttpRequest not supported"); } HTTP._factory(); } </script> <script type="text/javascript"> function showTopPosts(availElem, suffix) { if(!availElem)return; availElem.parentNode.insertBefore(document.createElement('br'), availElem); var topPostsDiv = document.createElement('div'); topPostsDiv.setAttribute('id', 'topPosts'+suffix); topPostsDiv.innerHTML = '<div style="margin: 0px 3% 0px 3%;background:#F9F9F9 none repeat scroll 0% 0%; border:1px solid #CCCCCC; color:#5B5B5B; font-size:10pt; font-style:normal; line-height:150%; padding:0px 10px;">' + '<table width="100%"><tbody><tr valign="middle"><td width="12" style="font-weight: bold;">置<br/>顶<br/>文<br/>章</td>' + '<td><ul id="' + 'recomm1' + suffix + '"></ul></td><td><ul id="' + 'recomm2' + suffix + '"></ul></td>' + '</tr></tbody></table></div>'; availElem.parentNode.insertBefore(topPostsDiv, availElem); var numTopPosts = 0; var i = 0; for(i = 0 ; i < Delicious.posts.length; ++i){ if(IsIn('topPost', Delicious.posts[i].t)){ numTopPosts++; } } var cond1 = document.getElementById('recomm1'+suffix); cond1.innerHTML = ''; var count = 0; for(i = 0; count < numTopPosts/2; ++i){ if(IsIn('topPost', Delicious.posts[i].t)){ count++; cond1.innerHTML += '<li><a href = "' + Delicious.posts[i].u + '">' + Delicious.posts[i].d + '</a></li>'; } } var cond2 = document.getElementById('recomm2'+suffix); cond2.innerHTML = ''; for(; i < Delicious.posts.length; ++i){ if(IsIn('topPost', Delicious.posts[i].t)){ cond2.innerHTML += '<li><a href = "' + Delicious.posts[i].u + '">' + Delicious.posts[i].d + '</a></li>'; } } availElem.parentNode.insertBefore(document.createElement('br'), availElem); } function doShowTopPosts() { showTopPosts(document.getElementById('Post.ascx_ViewPost_PreviousAndNextEntriesUp'), 'Up'); showTopPosts(document.getElementById('Post.ascx_ViewPost_PreviousAndNextEntriesDown'), 'Down'); } </script> <script type="text/javascript"> function urlToId(url) { var a1 = url.split('/'); var a2 = a1[a1.length - 1]; var a3 = a2.split('.'); return a3[0]; } var getFeedbackCountReq; var myBlogPosts = {}; var hotPostsContainer; function showHotPosts(ct) { hotPostsContainer = ct; for(i = 0; i < Delicious.posts.length; ++i){ var postID = urlToId(Delicious.posts[i].u); myBlogPosts[postID] = {url:Delicious.posts[i].u, title:Delicious.posts[i].d, feedbackCount:0}; } var idList = ''; for(var id in myBlogPosts){ idList += id + ','; } getFeedbackCountReq = HTTP.newRequest(); getFeedbackCountReq.onreadystatechange = handleGetFeedbackCountReq; getFeedbackCountReq.open('GET', '/NewCount.aspx?FeedbackCountStack=' + idList); getFeedbackCountReq.send(null); } function handleGetFeedbackCountReq() { if(getFeedbackCountReq.readyState==4){ if(getFeedbackCountReq.status==200){ handleGetFeedbackCountReq2(getFeedbackCountReq.responseText); } } } function handleGetFeedbackCountReq2(feedbackStr) { var feedbackList = feedbackStr.split(','); var i; for(i = 0; i < feedbackList.length; ++i){ var IDFeedbackCountPair = feedbackList[i].split('='); myBlogPosts[IDFeedbackCountPair[0]].feedbackCount = IDFeedbackCountPair[1]; } var myBlogPostsVector = []; for(var id in myBlogPosts){ myBlogPostsVector.push({"id":id, "url":myBlogPosts[id].url, "title":myBlogPosts[id].title, "feedbackCount":myBlogPosts[id].feedbackCount}); } myBlogPostsVector.sort(compareByFeedbackCount); var title = document.createElement('h3'); title.appendChild(document.createTextNode('本blog评论最多文章')); hotPostsContainer.appendChild(title); var NGList = ['http://blog.csdn.net/pongba/archive/2004/08/26/84978.aspx', 'http://blog.csdn.net/pongba/archive/2004/11/26/195052.aspx', 'http://blog.csdn.net/pongba/archive/2004/11/26/195075.aspx']; var maxNumHotPosts = 12 + NGList.length; if(myBlogPosts.length < maxNumHotPosts) maxNumHotPosts = myBlogPosts.length; var ul = document.createElement('ul'); for(i = 0; i < maxNumHotPosts; ++i){ if(IsIn(myBlogPostsVector[i].url, NGList))continue; var li = document.createElement('li'); var a = document.createElement('a'); a.setAttribute('href', myBlogPostsVector[i].url); a.appendChild(document.createTextNode(myBlogPostsVector[i].title)); li.appendChild(a); var sup = document.createElement('sup'); sup.setAttribute('style', 'color:red;'); sup.appendChild(document.createTextNode('(' + myBlogPostsVector[i].feedbackCount + ')')); li.appendChild(sup); ul.appendChild(li); } hotPostsContainer.appendChild(ul); } function compareByFeedbackCount(post1, post2) { return post2.feedbackCount - post1.feedbackCount; } function compareById(post1, post2){ return post2.id - post1.id; } </script> <script type="text/javascript"> function GetPositionalDiv() { var elems = getElements('articalinfo', 'p'); if(elems.length==0||elems.length>1)return null; return elems[0]; } /* get tags of this post */ function GetTags() { var thisURL = GetThisURL(); var tags; for(var i = 0; i < Delicious.posts.length ; i++){ var post = Delicious.posts[i]; if(post.u == thisURL){ tags = []; for(var j = 0; j < post.t.length; ++j){ if(post.t[j] == 'topPost')continue; tags.push(post.t[j]); } break; } } return tags; } /* tags are ordered by their importance, we assume that the more specific a tag is, the more important it will be, and the smaller a tag is, the more specific it will be */ function TagOrderPred(tag1, tag2) { return Delicious.tags[tag1] - Delicious.tags[tag2]; } /* find articles related to a particular _tag_ */ function BuildRelatedArticleList(tag) { var list = new Array(); for(var i = 0, post; post = Delicious.posts[i]; i++){ if(IsIn(tag, post.t) && post.u!=GetThisURL()){ list.push(post); } } return list; } function ShowRelatedArticles(ct, tags) { if(!tags)return null; var maxSize = 12; var ul = document.createElement('ul'); ul.setAttribute('id', 'my_related_posts'); var selectedPosts = new Array(); var currentSize = 0; tags.sort(TagOrderPred); // rating tags for(var k = 0; k < tags.length; k++){ var tag = tags[k]; var relatedPosts = BuildRelatedArticleList(tag); // remove those already selected ones relatedPosts = Unique(relatedPosts, selectedPosts); // if there's no related posts to this particular tag, keep going on if(relatedPosts.length == 0) continue; // make sure the total size doesn't exeed the maxSize if(currentSize + relatedPosts.length > maxSize){ var roomLeft = maxSize - currentSize; relatedPosts = RandomSelection(relatedPosts, roomLeft); } // add'em to the collection of selected posts selectedPosts = selectedPosts.concat(relatedPosts); var promptTxt = document.createTextNode('from tag '); var promptTxtDecorated = document.createElement('font'); promptTxtDecorated.setAttribute('size', '+1'); promptTxtDecorated.appendChild(promptTxt); ul.appendChild(promptTxtDecorated); var taglnk = document.createElement('a'); taglnk.setAttribute('href', 'http://del.icio.us/pongbablog/'+tag); taglnk.appendChild(document.createTextNode(tag)); var taglnkDecorated = document.createElement('font'); taglnkDecorated.setAttribute('size', '+2'); taglnkDecorated.appendChild(taglnk); ul.appendChild(taglnkDecorated); // create list element for every related posts for(var i = 0; i < relatedPosts.length; i++){ var li = document.createElement('li'); var a = document.createElement('a'); a.setAttribute('href', relatedPosts[i].u); a.appendChild(document.createTextNode(relatedPosts[i].d)); li.appendChild(a); ul.appendChild(li); } var br = document.createElement('br'); ul.appendChild(br); currentSize += relatedPosts.length; if(currentSize >= maxSize)break; } var title = document.createElement('h3'); title.appendChild(document.createTextNode("本blog相关文章")); ct.appendChild(title); ct.appendChild(ul); return selectedPosts; } function ShowRandomArticles(ct, filter) { if(!filter) filter = []; var ul = document.createElement('ul'); ul.setAttribute('id', 'my_random_posts'); var numArticles = Delicious.posts.length; var indices = new Array(); var maxNumShown = 12; if(numArticles < maxNumShown){ maxNumShown = numArticles; } for(var i = 0; i < maxNumShown;){ var randIndex = Math.floor(Math.random()*numArticles); if((Delicious.posts[randIndex].u!=GetThisURL())&& (!IsIn(randIndex, indices))&& (!IsIn(Delicious.posts[randIndex], filter))){ indices.push(randIndex); var a = document.createElement('a'); a.setAttribute('href', Delicious.posts[randIndex].u); a.appendChild(document.createTextNode(Delicious.posts[randIndex].d)); var li = document.createElement('li'); li.appendChild(a); ul.appendChild(li); i++; } } var title = document.createElement('h3'); title.appendChild(document.createTextNode("本blog随机文章")); ct.appendChild(title); ct.appendChild(ul); } function ShowTags(ct, tags) { if(!tags)return; var ul = document.createElement('ul'); ul.setAttribute('id', 'my_related_tags'); for(var i = 0; i < tags.length; i++){ var a = document.createElement('a'); a.setAttribute('href', 'http://del.icio.us/pongbablog/'+tags[i]); a.appendChild(document.createTextNode(tags[i] + '(' + Delicious.tags[tags[i]] + ')')); var aDecorated = document.createElement('font'); aDecorated.setAttribute('size', '+1'); aDecorated.appendChild(a); var li = document.createElement('li'); li.appendChild(aDecorated); li.appendChild(document.createTextNode(' ')); ul.appendChild(li); } var title = document.createElement('h3'); title.appendChild(document.createTextNode('本文相关tags')); ct.appendChild(title); ct.appendChild(ul); } function createDivWithId(id) { var element = document.createElement('div'); element.setAttribute('id', id); return element; } function Prepare() { var ct = GetPositionalDiv(); if(!ct)return false; ct.parentNode.insertBefore(createDivWithId('blog_related_posts'), ct); ct.parentNode.insertBefore(createDivWithId('blog_hot_posts'), ct); ct.parentNode.insertBefore(createDivWithId('blog_related_tags'), ct); ct.parentNode.insertBefore(createDivWithId('blog_random_posts'), ct); ct.parentNode.insertBefore(document.createElement('br'), ct); return true; } function ShowRelatedAll() { if(!Prepare())return; var tags = GetTags(); var alreadySelected = ShowRelatedArticles(document.getElementById('blog_related_posts'), tags); showHotPosts(document.getElementById('blog_hot_posts')); ShowTags(document.getElementById('blog_related_tags'), tags); ShowRandomArticles(document.getElementById('blog_random_posts'), alreadySelected); } </script> <h3>这个Blog上都写了哪些东东</h3> <div id="tags_cloud_delicious"></div> <script type="text/javascript"> function ShowTagCloud() { var ts = Delicious.tags; if(!ts)return; var html = ''; var ta = 0,tz=36; function s(a, b, i, x) { if(a>b){ var m=(a-b)/Math.log(x), v=a-Math.floor(Math.log(i)*m); }else{ var m=(b-a)/Math.log(x), v=Math.floor(Math.log(i)*m+a); } return v; } html += ('<style type="text/css">.delicious-tags{font-family:arial,sans-serif}.delicious-tags a{text-decoration:none}.delicious-tags a:hover{text-decoration:underline}.delicious-tags ul{list-style-type:none;margin:0;padding:0; text-align:justify}.delicious-cloud li{display:inline;text-align:justify;background-image:none !important;padding:0;margin:0}.delicious-cloud .delicious-tag-count{padding-left:0.2em;font-size:12px}.delicious-cloud li:before{content:"" !important}</style>'); var ca=[135,206,235], cz=[0,0,255], c=[]; html += ('<div class="delicious-tags" id="delicious-tags-pongbablog"><ul class="delicious-cloud">'); for(var t in ts){ if(t == 'topPost')continue; for(var i=0; i<3; i++) c[i]=s(ca[i], cz[i], ts[t]-ta, tz); var fs = s(12,35,ts[t]-ta,tz); html += ('<li style="font-size:'+fs+'px;line-height:1; display:inline;"><a style="color:rgb('+c[0]+','+c[1]+','+c[2]+')" href="http://del.icio.us/pongbablog/'+encodeURIComponent(t).replace('%2F','/')+'">'+t+'</a><span class="delicious-tag-count" style="font-size:12px;line-height:'+fs+'px;">('+ts[t]+')</span> </li>'); } html += ('</ul><br/>'); html += ('</div>'); document.getElementById('tags_cloud_delicious').innerHTML = html; } </script> <script type="text/javascript"> function doAllWorks(tags) { if(!tags){return;} if(typeof(Delicious) == 'undefined'||typeof(Delicious.posts) == 'undefined') { return; } Delicious.tags = tags; doShowTopPosts(); ShowRelatedAll(); ShowTagCloud(); } </script> <script type="text/javascript"> function runOnLoad(f) { if (runOnLoad.loaded) f( ); // If already loaded, just invoke f( ) now. else runOnLoad.funcs.push(f); // Otherwise, store it for later } runOnLoad.funcs = []; // The array of functions to call when the document loads runOnLoad.loaded = false; // The functions have not been run yet. // Run all registered functions in the order in which they were registered. // It is safe to call runOnLoad.run( ) more than once: invocations after the // first do nothing. It is safe for an initialization function to call // runOnLoad( ) to register another function. runOnLoad.run = function( ) { if (runOnLoad.loaded) return; // If we've already run, do nothing for(var i = 0; i < runOnLoad.funcs.length; i++) { try { runOnLoad.funcs[i]( ); } catch(e) { /* An exception in one function shouldn't stop the rest */ } } runOnLoad.loaded = true; // Remember that we've already run once. delete runOnLoad.funcs; // But don't remember the functions themselves. delete runOnLoad.run; // And forget about this function too! }; // Register runOnLoad.run( ) as the onload event handler for the window var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = runOnLoad.run; } else { window.onload = function() { runOnLoad.run(); oldonload(); }; } </script> <script type="text/javascript"> if (typeof window.Delicious == 'undefined') window.Delicious = {}; if(typeof(Delicious) == 'undefined') Delicious = {}; Delicious.Linkrolls = function() { return { render: function(o, posts) { var out = []; w = function (s) { out.push(s); }; posts.sort(function(b,a) { return ( (a.dt > b.dt) ? 1 : (a.dt < b.dt) ? -1 : 0 ); }); w('<div class="delicious-posts">'); w('<ul>'); for(var i=0,p;( i<o.count ) && ( p=posts[i] );i++){ w('<li class="delicious-post delicious-'+(i%2?'even':'odd')+'">'); w('<a class="delicious-link"' + ' href="' + p.u + '">'+this.htmlEscape(p.d)+'</a> '); if(p.n) w('<p class="delicious-extended">'+this.htmlEscape(p.n)+'</p>'); w('</li>'); } w('</ul>'); w('</div>'); return out.join(''); }, htmlEscape: function(s) { return (''+s).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); }, EOF: null }; }(); Delicious.Linkrolls_CB_51902 = function(posts) { var myhtml = Delicious.Linkrolls.render({"user":"pongba","usertags":"shared-reading","version":"2","count":"15","sort":"date","extended":true,"icon":"s","name":true,"showadd":true,"BASE_URL":"http:\/\/delicious.com","STATIC_URL":"http:\/\/l.yimg.com\/hr\/10374"}, posts); document.getElementById('delicious_shared_reading').innerHTML = myhtml; }; Delicious.Linkrolls_TL_SHARE = function(posts) { var myhtml = Delicious.Linkrolls.render({"user":"pongba","usertags":"toplanguage","version":"2","count":"15","sort":"date","extended":true,"icon":"s","name":true,"showadd":true,"BASE_URL":"http:\/\/delicious.com","STATIC_URL":"http:\/\/l.yimg.com\/hr\/10374"}, posts); document.getElementById('toplang_comments').innerHTML = myhtml; }; function DeliciousPrepare1(posts) { Delicious.posts = posts; } </script> <script type="text/javascript"> if (typeof window.Delicious == "undefined") window.Delicious = {}; Delicious.BLOGBADGE_DEFAULT_CLASS = 'delicious-blogbadge-line'; if (typeof(Delicious)=='undefined') Delicious = {}; if (typeof(Delicious.BlogBadge)=='undefined') { if (!Object.prototype.hasOwnProperty) { Object.prototype.hasOwnProperty = function(p) { return (typeof this[p] != 'undefined') && (this.constructor.prototype[p] !== this[p]); } } Delicious.BlogBadge = function() { return { DEBUG: false, url_root: Delicious.URL_ROOT || 'http://delicious.com', post_url_root: Delicious.POST_URL_ROOT || 'http://delicious.com/save', json_url_root: Delicious.JSON_URL_ROOT || 'http://feeds.delicious.com/v2/json/urlinfo', static_url_root: Delicious.STATIC_URL_ROOT || 'http://l.yimg.com/hr', default_class: "delicious-blogbadge-tall", posts_count: 5, did_init: false, badges: {}, log: function(msg) { if (this.DEBUG) if (window.console && console.log) console.log(msg); }, init: function() { if (arguments.callee.done) return; arguments.callee.done = true; if (Delicious.BLOGBADGE_DEFAULT_CLASS) { Delicious.BlogBadge.default_class = Delicious.BLOGBADGE_DEFAULT_CLASS; } this.badges = {}; // HACK: Packed version of md5.js is at the bottom of this file. // this.insertExtJSLibs(); this.insertBadgeCSS(); }, onload: function() { if (arguments.callee.done) return; arguments.callee.done = true; if(this.noAvailDiv)return; this.fetchBadgeJSON(); }, insertExtJSLibs: function() { this.forEach([ this.static_url_root+'/js/md5.js' ], function(u) { var scr = document.createElement("script"); scr.setAttribute("type", "text/javascript"); scr.setAttribute("src", u); document.getElementsByTagName("head").item(0).appendChild(scr); }); }, insertBadgeCSS: function() { var bcss = document.getElementById('delicious-blogbadge-css'); if (!bcss) { bcss = this.el('link', { 'id': 'delicious-blogbadge-css', 'type': 'text/css', 'rel': 'stylesheet', 'href': this.static_url_root+'/css/blogbadge.css' }, []); document.getElementsByTagName('head')[0].appendChild(bcss); } bcss = null; }, register: function(divid, url, title, opts) { var hash = hex_md5(url); var badge = { 'divid': divid, 'url': url, 'hash': hash, 'title':title, 'opts': opts||{} }; this.badges[hash] = badge; this.replaceChildNodes( document.getElementById(badge.divid), this.renderPostButton(badge) ); }, writeBadge: function(divid, url, title, opts, classname) { if (!classname) classname = this.default_class; var deliciousDivWrapper = document.createElement('div'); deliciousDivWrapper.innerHTML = '<div class="'+classname+'" id="'+divid+'"></div>'; var availElem = GetPositionalDiv(); if(!availElem) { this.noAvailDiv = true; return; } availElem.parentNode.insertBefore(document.createElement('br'), availElem); availElem.parentNode.insertBefore(deliciousDivWrapper, availElem); availElem.parentNode.insertBefore(document.createElement('br'), availElem); this.register(divid, url, title, opts); }, fetchBadgeJSON: function() { var json_url = this.json_url_root + "?callback=Delicious.BlogBadge.handleBadgeJSON" + "&noCacheIE="+(new Date()).getTime(); var showposts = false; for (hash in this.badges) { if (!this.badges.hasOwnProperty(hash)) continue; var badge = this.badges[hash]; json_url += "&hash="+encodeURIComponent(hash); if (!showposts && badge.opts.showposts) { showposts = true; json_url += "&showposts=yes&count="+this.posts_count; } } // TODO: Make work in XHTML pages with namespaces. var scr = document.createElement("script"); scr.setAttribute("type", "text/javascript"); scr.setAttribute("src", json_url); scr.setAttribute("id", 'delicious-blogbadge-json'); this.script_ele = scr; document.getElementsByTagName("head").item(0).appendChild(this.script_ele); }, handleBadgeJSON: function(data) { this.log(data); this.log(this.badges); for (var i=0,rec; rec=data[i]; i++) { var badge = this.badges[rec.hash]; if (badge && !badge.loaded) { this.buildBadge(badge, rec); badge.loaded = true; } } for (hash in this.badges) { if (!this.badges.hasOwnProperty(hash)) continue; var badge = this.badges[hash]; if (badge.loaded) continue; this.buildBadge(badge, { url: badge.url, total_posts: 0, top_tags: [] }); } document.getElementsByTagName("head").item(0).removeChild(this.script_ele); this.script_ele = null; }, buildBadge: function(badge, data) { badge.data = data; this.replaceChildNodes( document.getElementById(badge.divid), this.renderBadge(badge) ); }, buildPostURL: function(badge) { return this.post_url_root + '?url='+encodeURIComponent(badge.url)+ '&title='+encodeURIComponent(badge.title || '')+ '&jump=yes&partner=delbg'; }, renderPostButton: function(badge) { var el = this.bind(this.el); var post_url = this.buildPostURL(badge); return [ el('a', {'class':'save-to-link', 'href':post_url, 'title':'Bookmark '+badge.title+' on Delicious'}, [ el('span', {'class':'save-to-link-label'}, ['bookmark this on Delicious']) ]) ]; }, renderBadge: function(badge) { var el = this.bind(this.el); var map = this.bind(this.map); var data = badge.data; var total_posts = data.total_posts || 0; var top_tags = []; for (t in data.top_tags) { if (!data.top_tags.hasOwnProperty(t)) continue; top_tags.push(t); } top_tags.sort(function(a,b) { return ( data.top_tags[b] - data.top_tags[a] ); }); var posts = []; if (badge.opts.showposts) { for (var i=0, post; (i<this.posts_count) && (post=badge.data.posts[i]); i++) { posts.push(post); } } var post_bookmark_url = this.buildPostURL(badge); return [ this.renderPostButton(badge), (total_posts > 0) ? el('a', {'class':'url-link', 'href':this.url_root+'/url/'+data.hash}, [ el('span', {'class':'post-count-label-before'}, ['saved by ']), el('span', {'class':'post-count'}, [ total_posts ]), el('span', {'class':'post-count-label-after'}, (total_posts>1) ? [' other people'] : [' other person'] ), ]) : [ el('a', {'class':'empty-save-to-link', 'href':post_bookmark_url}, [ el('span', {'class':'empty-save-to-link-label'}, ['save this']), ]), el('span', {'class':'empty-message'}, [ 'be the first to bookmark this page!' ]) ], (! (total_posts > 0 && top_tags.length > 0) ) ? '' : [ el('div', {'class':'top-tags-container'}, [ el('span', {'class':'top-tags-title'}, ['tags: ']), el('ul', {'class':'top-tags'}, map(function(t) { return [ el('li', {}, [ el('a', {'href':this.url_root+'/tag/'+t, 'title':t}, [t]) ]), ' ' ]; }, top_tags) ) ]) ], (! (badge.opts.showposts && posts.length) ) ? '' : [ el('span', {'class':'latest-posts'}, [ el('span', {'class':'latest-posts-label'}, ['recent bookmarks: ']), el('ul', {}, map( function(post) { return el('li', {'class':'xfolkentry'}, [ el('a', {'class':'taggedlink', 'href':post.u}, [post.n]), (!post.d) ? '' : el('blockquote', {'class':'description'}, [post.d]), el('div', {'class':'meta'}, [ el('span', {'class':'meta-label-by'}, [' by ']), el('a', {'class':'author', 'href':this.url_root+'/'+post.un}, [post.un]), (!post.t.length) ? '' : [ el('span', {'class':'meta-label-to'}, [' to ']), el('ul', {'class':'tags'}, map(function(t) { return [ el('li', {'class':'tag'}, [ el('a', {'rel':'tag', 'href':this.url_root+'/'+post.un+'/tag/'+t}, [t]) ]), ' ']; }, post.t)) ], el('span', {'class':'meta-label-at'}, [' at ']), el('abbr', {'class':'created','title':post.dt+'Z'}, [post.dt+'Z']), ]) ]); }, posts)) ]), ], ' ', el('br',{},[]) ]; }, bind: function(func) { var obj = this; return function() { return func.apply(obj, arguments) }; }, forEach: function(list, fn) { fn = this.bind(fn); for (var i=0; i<list.length; i++) fn(list[i]); }, filter: function(fn, list) { var rv = []; fn = this.bind(fn); for (var i=0; i<list.length; i++) if (fn(list[i])) rv[rv.length] = list[i]; return rv; }, map: function(fn, list) { var rv = []; fn = this.bind(fn); for (var i=0; i<list.length; i++) rv[rv.length] = fn(list[i]); return rv; }, replaceChildNodes: function(parent, nodes) { while (parent.firstChild) parent.removeChild(parent.firstChild); return this.appendChildNodes(parent, nodes); }, appendChildNodes: function(parent, nodes) { if (!nodes || !nodes.length) return; for (var i=0; i<nodes.length; i++) { var node = nodes[i]; if (!node) continue; if (node.nodeType) parent.appendChild(node); else if ( (typeof(node) == 'object') && node.length) this.appendChildNodes(parent, node); else parent.appendChild(document.createTextNode(''+node)); } }, el: function(name, attrs, nodes) { var elem = document.createElement(name); if (attrs) for (k in attrs) { if (!attrs.hasOwnProperty(k)) continue; var v = attrs[k]; if (k.substring(0, 2) == "on") { if (typeof(v) == "string") { v = new Function(v); } elem[k] = v; } else { elem.setAttribute(k, v); } switch(k) { // MSIE seems to want this. case 'class': elem.className = v; break; } } if (nodes) this.appendChildNodes(elem, nodes); return elem; }, EOF:null }; }(); } // HACK: Packed version of http://pajhome.org.uk/crypt/md6/md5.js eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('e 1i=0;e 1g="";e p=8;f 1f(s){g K(A(D(s),s.o*p))}f 1w(s){g S(A(D(s),s.o*p))}f 1N(s){g L(A(D(s),s.o*p))}f 2b(w,v){g K(I(w,v))}f 2a(w,v){g S(I(w,v))}f 2c(w,v){g L(I(w,v))}f 2i(){g 1f("1R")=="1O"}f A(x,G){x[G>>5]|=1U<<((G)%E);x[(((G+1V)>>>9)<<4)+14]=G;e a=24;e b=-1Y;e c=-1X;e d=2h;z(e i=0;i<x.o;i+=16){e Y=a;e W=b;e X=c;e 1b=d;a=l(a,b,c,d,x[i+0],7,-2d);d=l(d,a,b,c,x[i+1],12,-28);c=l(c,d,a,b,x[i+2],17,29);b=l(b,c,d,a,x[i+3],22,-1T);a=l(a,b,c,d,x[i+4],7,-1Z);d=l(d,a,b,c,x[i+5],12,2j);c=l(c,d,a,b,x[i+6],17,-1P);b=l(b,c,d,a,x[i+7],22,-1Q);a=l(a,b,c,d,x[i+8],7,1S);d=l(d,a,b,c,x[i+9],12,-25);c=l(c,d,a,b,x[i+10],17,-26);b=l(b,c,d,a,x[i+11],22,-2f);a=l(a,b,c,d,x[i+12],7,2e);d=l(d,a,b,c,x[i+13],12,-2g);c=l(c,d,a,b,x[i+14],17,-27);b=l(b,c,d,a,x[i+15],22,1M);a=h(a,b,c,d,x[i+1],5,-1t);d=h(d,a,b,c,x[i+6],9,-1s);c=h(c,d,a,b,x[i+11],14,1u);b=h(b,c,d,a,x[i+0],20,-1v);a=h(a,b,c,d,x[i+5],5,-1r);d=h(d,a,b,c,x[i+10],9,1q);c=h(c,d,a,b,x[i+15],14,-1l);b=h(b,c,d,a,x[i+4],20,-1k);a=h(a,b,c,d,x[i+9],5,1m);d=h(d,a,b,c,x[i+14],9,-1n);c=h(c,d,a,b,x[i+3],14,-1p);b=h(b,c,d,a,x[i+8],20,1o);a=h(a,b,c,d,x[i+13],5,-1x);d=h(d,a,b,c,x[i+2],9,-1y);c=h(c,d,a,b,x[i+7],14,1I);b=h(b,c,d,a,x[i+12],20,-1H);a=k(a,b,c,d,x[i+5],4,-1J);d=k(d,a,b,c,x[i+8],11,-1K);c=k(c,d,a,b,x[i+11],16,1L);b=k(b,c,d,a,x[i+14],23,-1G);a=k(a,b,c,d,x[i+1],4,-1F);d=k(d,a,b,c,x[i+4],11,1A);c=k(c,d,a,b,x[i+7],16,-1z);b=k(b,c,d,a,x[i+10],23,-1B);a=k(a,b,c,d,x[i+13],4,1C);d=k(d,a,b,c,x[i+0],11,-1E);c=k(c,d,a,b,x[i+3],16,-1D);b=k(b,c,d,a,x[i+6],23,1W);a=k(a,b,c,d,x[i+9],4,-2z);d=k(d,a,b,c,x[i+12],11,-2F);c=k(c,d,a,b,x[i+15],16,2G);b=k(b,c,d,a,x[i+2],23,-2D);a=m(a,b,c,d,x[i+0],6,-2B);d=m(d,a,b,c,x[i+7],10,2I);c=m(c,d,a,b,x[i+14],15,-2O);b=m(b,c,d,a,x[i+5],21,-2M);a=m(a,b,c,d,x[i+12],6,2J);d=m(d,a,b,c,x[i+3],10,-2H);c=m(c,d,a,b,x[i+10],15,-2A);b=m(b,c,d,a,x[i+1],21,-2p);a=m(a,b,c,d,x[i+8],6,2q);d=m(d,a,b,c,x[i+15],10,-2o);c=m(c,d,a,b,x[i+6],15,-2n);b=m(b,c,d,a,x[i+13],21,2m);a=m(a,b,c,d,x[i+4],6,-2r);d=m(d,a,b,c,x[i+11],10,-2k);c=m(c,d,a,b,x[i+2],15,2y);b=m(b,c,d,a,x[i+9],21,-2t);a=u(a,Y);b=u(b,W);c=u(c,X);d=u(d,1b)}g H(a,b,c,d)}f F(q,a,b,x,s,t){g u(Z(u(u(a,q),u(x,t)),s),b)}f l(a,b,c,d,x,s,t){g F((b&c)|((~b)&d),a,b,x,s,t)}f h(a,b,c,d,x,s,t){g F((b&d)|(c&(~d)),a,b,x,s,t)}f k(a,b,c,d,x,s,t){g F(b^c^d,a,b,x,s,t)}f m(a,b,c,d,x,s,t){g F(c^(b|(~d)),a,b,x,s,t)}f I(w,v){e C=D(w);1d(C.o>16)C=A(C,w.o*p);e P=H(16),V=H(16);z(e i=0;i<16;i++){P[i]=C[i]^2L;V[i]=C[i]^2N}e 1c=A(P.18(D(v)),19+v.o*p);g A(V.18(1c),19+2C)}f u(x,y){e O=(x&N)+(y&N);e 1a=(x>>16)+(y>>16)+(O>>16);g(1a<<16)|(O&N)}f Z(T,M){g(T<<M)|(T>>>(E-M))}f D(n){e B=H();e J=(1<<p)-1;z(e i=0;i<n.o*p;i+=p)B[i>>5]|=(n.2l(i/p)&J)<<(i%E);g B}f L(B){e n="";e J=(1<<p)-1;z(e i=0;i<B.o*E;i+=p)n+=2s.2x((B[i>>5]>>>(i%E))&J);g n}f K(r){e U=1i?"2w":"2v";e n="";z(e i=0;i<r.o*4;i++){n+=U.R((r[i>>2]>>((i%4)*8+4))&1e)+U.R((r[i>>2]>>((i%4)*8))&1e)}g n}f S(r){e 1h="2u+/";e n="";z(e i=0;i<r.o*4;i+=3){e 1j=(((r[i>>2]>>8*(i%4))&Q)<<16)|(((r[i+1>>2]>>8*((i+1)%4))&Q)<<8)|((r[i+2>>2]>>8*((i+2)%4))&Q);z(e j=0;j<4;j++){1d(i*8+j*6>r.o*E)n+=1g;2K n+=1h.R((1j>>6*(3-j))&2E)}}g n}',62,175,'||||||||||||||var|function|return|md5_gg|||md5_hh|md5_ff|md5_ii|str|length|chrsz||binarray|||safe_add|data|key|||for|core_md5|bin|bkey|str2binl|32|md5_cmn|len|Array|core_hmac_md5|mask|binl2hex|binl2str|cnt|0xFFFF|lsw|ipad|0xFF|charAt|binl2b64|num|hex_tab|opad|oldb|oldc|olda|bit_rol|||||||||concat|512|msw|oldd|hash|if|0xF|hex_md5|b64pad|tab|hexcase|triplet|405537848|660478335|568446438|1019803690|1163531501|187363961|38016083|701558691|1069501632|165796510|643717713|373897302|b64_md5|1444681467|51403784|155497632|1272893353|1094730640|681279174|722521979|358537222|1530992060|35309556|1926607734|1735328473|378558|2022574463|1839030562|1236535329|str_md5|900150983cd24fb0d6963f7d28e17f72|1473231341|45705983|abc|1770035416|1044525330|0x80|64|76029189|1732584194|271733879|176418897|||||1732584193|1958414417|42063|1502002290|389564586|606105819|b64_hmac_md5|hex_hmac_md5|str_hmac_md5|680876936|1804603682|1990404162|40341101|271733878|md5_vm_test|1200080426|1120210379|charCodeAt|1309151649|1560198380|30611744|2054922799|1873313359|145523070|String|343485551|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|0123456789abcdef|0123456789ABCDEF|fromCharCode|718787259|640364487|1051523|198630844|128|995338651|0x3F|421815835|530742520|1894986606|1126891415|1700485571|else|0x36363636|57434055|0x5C5C5C5C|1416354905'.split('|'),0,{})) </script> <script type="text/javascript"> runOnLoad(function() { var note1 = document.createElement('div'); note1.innerHTML = '<div style="background:#000000;color:#ffffff;text-align:center;padding:10px 0px;">本博客已经迁移至 http://mindhacks.cn ,此处保留作为镜像,但不保证一定同步更新所有内容。原订阅 http://blog.csdn.net/pongba/rss.aspx (原始 Feed) 的朋友请转为订阅永久 feed : http://mindhacks.cn/feed/</div>'; var ct = GetPositionalDiv(); if(ct){ ct.parentNode.insertBefore(document.createElement('br'), ct); ct.parentNode.insertBefore(note1, ct); ct.parentNode.insertBefore(document.createElement('br'), ct); } }); </script> <script type="text/javascript"> Delicious.BlogBadge.init(); runOnLoad(function() { Delicious.BlogBadge.writeBadge("delicious-blogbadge-1", location.href, document.title, {}); Delicious.BlogBadge.onload(); }); </script> <script type="text/javascript"> runOnLoad(function( ){ function newScript( src ) { var script = document.createElement("script"); script.setAttribute("type", "text/javascript"); script.setAttribute("src", src); return script; } document.body.appendChild(newScript("http://feeds.delicious.com/v2/json/pongbablog?count=100&callback=DeliciousPrepare1")); document.body.appendChild(newScript("http://feeds.delicious.com/v2/json/tags/pongbablog?count=100&callback=doAllWorks")); document.body.appendChild(newScript("http://twitter.com/statuses/user_timeline/pongba.json?callback=twitterCallback2&count=8")); document.body.appendChild(newScript("http://feeds.delicious.com/v2/json/pongba/shared-reading?count=15&callback=Delicious.Linkrolls_CB_51902")); document.body.appendChild(newScript("http://feeds.delicious.com/v2/json/pongba/toplanguage?count=15&callback=Delicious.Linkrolls_TL_SHARE")); }); </script>
文章分类
C++
Andrei Alexandrescu
Andrew Lumsdaine
Bjarne Stroustrup
boost
C++ Standard Commitee
Doug Gregor
Hans J. Boehm
Jaakko Jarvi
Jeremy G. Siek
Matthew Wilson
newsgroups
boost.Developer
boost.User
comp.lang.c++.moderated
comp.std.c++
TopLanguage
Open Source
Ant
codeplex
Danga
Google AJAX Search API
Google Code Prettify
Google Web Toolkit
Hadoop
MS shared source initiative
notepad++
STLSoft
不认识的朋友们
Delphij
fatalerror99
flow with the life
Glacier
jimaxsoft
lifesinger@淘宝UED
Mr. 6
realazy
Robbin
SpiritEpic
TK
wuyizi
Yelz
丁丁虫
付翀
冰云
刘慈欣
卢昌海
吴欣安(atppp)
周爱民
和菜头
姬十三
守望轩
小花@BlogBus
林达华
浦宇平
白鸦
程化
罗浩|Startup Game
阮一峰
霍炬
飞之鸿
高远
鲍盛
机器学习/数据挖掘/信息检索/自然语言处理/认知科学/人工智能
AAAI
Apex
arXiv
Charles Kemp
Christopher Bishop
Christopher Manning
Cognitive Daily
Dan Jurafsky
David MacKay
ECML PKDD
Geoffrey Hinton
Herbert Simon
ICML
IJCAI
Jeff Hawkins
Jiawei Han
JMLR
Josh Tenenbaum
Larry Wasserman
Lucene
Marvin Minsky
MIT AI Lab
MIT Computational Cognitive Science Group
Mitchell Marcus
ML
NetLab
NIPS
Peter Norvig
Stanford AI Lab
Stanford NLP Lab
Stephen Boyd
Tom Mitchell
Trends in Cognitive Science
Vladimir Vapnik
Weka
Zhihua Zhou
技术
Coding Horror
High Scalability
Reddit
Stack Overflow
Steve Yegge
代码发芽网
淘宝UED团队
淘宝数据仓库团队
玩聚网
移山之道
其它
Gigapedia
Scientific American
Scientific American Mind
科学松鼠会
科幻世界
认识的朋友们
alai
chenyufei
dd
DreamHead
Googol
Jawley
Joyfire
littlestone
lxwde
Matrix67
realfun
RiceBall
roofalison
soloist
Tinyfool
windstorm
YongSun
书剑
云风
余晟
元凯宁
冯大辉(Fenng)
刘新宇
刘江@图灵
史晓明
吴新雨
周星星
周筠@博文视点
孟岩
张志强|阅微堂
张振
徐宥|4G Spaces
方舟@博文视点
曾登高
李笑来|Pure Pleasure
杨军
杨文博
熊节
王信文
王康生
苏杰@阿里巴巴
范怀宇
荣耀
莫华枫
蒋涛
袁泳(g9)|负暄琐话
许式伟
谢东升
谷文栋|Beyond Search
邹欣@MSRA
郑昀
阿朱
陈冀康@华章
陈怀兴
鲍志云
存档

原创  旧话重提:pImpl惯用手法的背后 收藏

                       旧话重提:pImpl惯用手法的背后

                                                  刘未鹏

 

pImpl惯用手法已经太老了,老得人们已经记不得它是什么时候被提出的了。像这么一个老得牙都掉了的东东几乎是肯定讲不出什么新意出来的。

本文也不例外,只不过,这里我们并不想提出什么新的创意,而是对pImpl背后的机制作一个探究和总结。

 

城门失火 殃及池鱼

pImpl惯用手法的运用方式大家都很清楚,其主要作用是解开类的使用接口和实现的耦合。如果不使用pImpl惯用手法,代码会像这样:

       //c.hpp

        #include<x.hpp>

class C

        {

        public:

            void f1();

        private:

            X x; //X的强耦合

        };

像上面这样的代码,C与它的实现就是强耦合的,从语义上说,x成员数据是属于C的实现部分,不应该暴露给用户。从语言的本质上来说,在用户的代码中,每一次使用”new C””C c1”这样的语句,都会将X的大小硬编码到编译后的二进制代码段中(如果X有虚函数,则还不止这些)——这是因为,对于”new C”这样的语句,其实相当于operator new(sizeof(C) )后面再跟上C的构造函数,而”C c1”则是在当前栈上腾出sizeof(C)大小的空间,然后调用C的构造函数。因此,每次X类作了改动,使用c.hpp的源文件都必须重新编译一次,因为X的大小可能改变了。

在一个大型的项目中,这种耦合可能会对build时间产生相当大的影响。

pImpl惯用手法可以将这种耦合消除,使用pImpl惯用手法的代码像这样:

        //c.hpp

        class X;  //用前导声明取代include

        class C

        {

         ...

         private:

            X* pImpl; //声明一个X*的时候,class X不用完全定义

        };

在一个既定平台上,任何指针的大小都是相同的。之所以分为X*Y*这些各种各样的指针,主要是提供一个高层的抽象语义,即该指针到底指向的是那个类的对象,并且,也给编译器一个指示,从而能够正确的对用户进行的操作(如调用X的成员函数)决议并检查。但是,如果从运行期的角度来说,每种指针都只不过是个32位的长整型(如果在64位机器上则是64位,根据当前硬件而定)。

正由于pImpl是个指针,所以这里X的二进制信息(sizeof(C)等)不会被耦合到C的使用接口上去,也就是说,当用户”new C””C c1”的时候,编译器生成的代码中不会掺杂X的任何信息,并且当用户使用C的时候,使用的是C的接口,也与X无关,从而X被这个指针彻底的与用户隔绝开来。只有C知道并能够操作pImpl成员指向的X对象。

 

防火墙

“修改X的定义会导致所有使用C的源文件重新编译”这种事就好比“城门失火,殃及池鱼”,其原因是“护城河”离“城门”太近了(耦合)。

pImpl惯用手法又被成为“编译期防火墙”,什么是“防火墙”,指针?不是。C++的编译模式为“分离式编译”,即不同的源文件是分开编译的。也就是说,不同的源文件之间有一道天然的防火墙,一个源文件“失火”并不会影响到另一个源文件。

但是,这里我们考虑的是头文件,如果头文件“失火”又当如何呢?头文件是不能直接编译的,它包含于源文件中,并作为源文件的一部分被一起编译。

这也就是说,如果源文件S.cpp使用了C.hpp,那么class C的(接口部分的)变动将无可避免的导致S.CPP的重新编译。但是作为class C的实现部分的class X却完全不应该导致S.cpp的重新编译。

因此,我们需要把class X隔绝在C.hpp之外。这样,每个使用class C的源文件都与class X隔离开来(与class X不在同一个编译单元)。但是,既然class C使用了class X的对象来作为它的实现部分,就无可避免的要“依赖”于class X。只不过,这个“依赖”应该被描述为:“class C的实现部分依赖于class X”,而不应该是“class C的用户使用接口部分依赖于class X”。

如果我们直接将X的对象写在class C的数据成员里面,则显而易见,使用class C的用户“看到”了不该“看到”的东西——class X——它们之间产生了耦合。然而,如果使用一个指向class X的指针,就可以将X的二进制信息“推”到class C的实现文件中去,在那里,我们#include”x.hpp”,定义所有的成员函数,并依赖于X的实现,这都无所谓,因为C的实现本来就依赖于X,重要的是:此时class X的改动只会导致class C的实现文件重新编译,而用户使用class C的源文件则安然无恙!

    指针在这里充当了一座桥。将依赖信息“推”到了另一个编译单元,与用户隔绝开来。而防火墙是C++编译器的固有属性。

 

穿越C++编译期防火墙

是什么穿越了C++编译期防火墙?是指针!使用指针的源文件“知道”指针所指的是什么对象,但是不必直接“看到”那个对象——它可能在另一个编译单元,是指针穿越了编译期防火墙,连接到了那个对象。

从某种意义上说,只要是代表地址的符号都能够穿越C++编译期防火墙,而代表结构(constructs)的符号则不能。

    例如函数名,它指的是函数代码的始地址,所以,函数能够声明在一个编译单元,但定义在另一个编译单元,编译器会负责将它们连接起来。用户只要得到函数的声明就可以使用它。而类则不同,类名代表的是一个语言结构,使用类,必须知道类的定义,否则无法生成二进制代码。变量的符号实质上也是地址,但是使用变量一般需要变量的定义,而使用extern修饰符则可以将变量的定义置于另一个编译单元中。

发表于 @ 2004年09月12日 20:20:00 | 评论( loading... ) | 编辑| 举报| 收藏

旧一篇:《C++ Template Metaprogramming》译序——经典之后的经典 | 新一篇:《C++ Template Metaprogramming》附录A——预处理元编程

  • 发表评论
  • 评论内容:
  •  
Copyright © pongba
Powered by CSDN Blog