﻿<?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>BlogJava-赖猫，在学习-文章分类-Effecitive C++读书笔记</title><link>http://www.blogjava.net/amenglai/category/43684.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 05 May 2010 13:58:22 GMT</lastBuildDate><pubDate>Wed, 05 May 2010 13:58:22 GMT</pubDate><ttl>60</ttl><item><title>Effecitive C++读完了。</title><link>http://www.blogjava.net/amenglai/articles/320109.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 05 May 2010 03:31:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/320109.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/320109.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/320109.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/320109.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/320109.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt">今天终于把这本书读完了，泛型编程部分因为自己用的很少，收货不大，其它部分读过以后，的确可以加深理解，尤其是对照《C++ Primer》，在理解上会有很大的进步。<br />
这本书，我读的时间很零碎，一般只是早上读，晚上回家因为要呼哧呼哧的写点东西，实在是没时间读，所以花的时间比较多。<img src="/CuteSoft_Client/CuteEditor/images/face23.gif" align="absMiddle" border="0"  alt="" />虽然很零碎，但是收货很大，大概是因为从来没给自己设置任何的deadline，没有压力，也就可以慢慢的读，慢慢的思考。<br />
另外因为这本书更加关注的是语言的本身，所以肯定没有读PEAA之列的那么费劲，也很适合零碎的时间来阅读。<br />
哎，我写了这么多年Java都没读过Effecitive java。最后再感慨一下吧。<br />
明天，我会回到我喜欢的java，去读《设计模式精解》。<br />
依然是早上阅读，希望这次的阅读，能够对我目前的代码重构有即时的帮助。</span>
 <img src ="http://www.blogjava.net/amenglai/aggbug/320109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amenglai/" target="_blank">amenglai</a> 2010-05-05 11:31 <a href="http://www.blogjava.net/amenglai/articles/320109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Effecitive C++读书笔记 Chapter4 设计与声明</title><link>http://www.blogjava.net/amenglai/articles/316139.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Mon, 22 Mar 2010 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/316139.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/316139.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/316139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/316139.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/316139.html</trackback:ping><description><![CDATA[&nbsp;
<h1>Item18 Make interfaces easy to use correctly and hard to use incorrectly.<span style="font-family: 宋体">让接口容易被正确使用，不易被误用</span></h1>
<h1><span style="font-weight: normal; font-size: 11pt; font-family: 宋体">好的接口设计应该是既容易被正确使用，又不易被误用。</span></h1>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">就例如书中的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Sample</span><span style="font-size: 11pt">，关于时间的，我们一般的做法就是在创建</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Day</span><span style="font-size: 11pt">对象时，追加校验函数来判断年月日是不是有效。</span></p>
<h3><span style="font-family: 宋体">建议的做法一是：创建新的类型</span></h3>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">定义：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">class Month {</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">public:</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&nbsp;&nbsp; static Month Jan() {return Month(1); }</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&nbsp;&nbsp; static Month feb() {return Month(2); }</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">&#8230;</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">private Month(int m);</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">};</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Date d(Month::Mar(), Day(30), Year(1995) );</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">为啥不直接使用静态变量？</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">参考</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Item4 P30</span><span style="font-size: 11pt">，简单说就是不能保证在使用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">non-local static objects</span><span style="font-size: 11pt">时，这个对象就已经初始化了。如果</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">non-local static objects</span><span style="font-size: 11pt">在另一个文件了，又恰巧没有初始化，系统当然就会翘辫子了。</span></p>
<h3><span style="font-family: 宋体">另一种方法：加上</span>const<span style="font-family: 宋体">来限制</span>type<span style="font-family: 宋体">可以做的事情。</span></h3>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">先参考</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Item3 P19</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">class Rational { </span><span style="font-size: 11pt">&#8230;</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">};</span></p>
<p style="margin-bottom: 0pt"><strong><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">const</span></strong><span style="font-size: 11pt; font-family: 'Arial','sans-serif'"> Rational operator*(const Rational &amp;lhs, const Rational &amp;rhs);</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">之所以强制设置为</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">const</span><span style="font-size: 11pt">就是为了避免</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">client</span><span style="font-size: 11pt">在使用时出错。因为如果没有</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">clien</span><span style="font-size: 11pt">，那么：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Rational a,b,c;</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">&#8230;</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">(a*b)=c</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">这种写法是对的，但是如果</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">a</span><span style="font-size: 11pt">，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">b</span><span style="font-size: 11pt">是内置类型，这种写法就是错误的。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; color: red">除非有必要，否则就要保证你的类型</span><span style="font-size: 11pt; color: red; font-family: 'Arial','sans-serif'">type</span><span style="font-size: 11pt; color: red">的行为和内置类型一致。</span></p>
<h3><span style="font-family: 宋体">一致性导致接口容易被正确使用。</span></h3>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">STL</span><span style="font-size: 11pt">是榜样，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">java</span><span style="font-size: 11pt">在这里成了反面教材，因为如果想知道容器内对象的数量，用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Array</span><span style="font-size: 11pt">，要访问属性</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">length</span><span style="font-size: 11pt">，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">String</span><span style="font-size: 11pt">要用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">length</span><span style="font-size: 11pt">函数，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">ArrayList</span><span style="font-size: 11pt">要用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">size</span><span style="font-size: 11pt">函数，这就是不一致性。</span></p>
<h3><span style="font-family: 宋体">使用</span>std::tr1::shared_ptr<span style="font-family: 宋体">，消除</span>client<span style="font-family: 宋体">对资源管理的责任</span></h3>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">找出以下写法的两个易错的地方：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Investment* createInvestment();</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">1 </span><span style="font-size: 11pt">忘记删除</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">createInvestment()</span><span style="font-size: 11pt">返回的指针</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">2 </span><span style="font-size: 11pt">删除这个指针多次</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">so</span><span style="font-size: 11pt">，修改定义：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std::tr1::shared_ptr&lt; Investment &gt; createInvestment();</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">如果出现这种情形：从</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">createInvestment</span><span style="font-size: 11pt">得到</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Investment*</span><span style="font-size: 11pt">的函数要把这个指针传递个给叫做</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">getRidOfInvestment</span><span style="font-size: 11pt">，由</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">getridOfInvestment</span><span style="font-size: 11pt">取代使用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">delete</span><span style="font-size: 11pt">。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">这里就出现了一个新的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">client</span><span style="font-size: 11pt">易错的点，用户或许会使用错的资源释放机制。因为</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">delete</span><span style="font-size: 11pt">被</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">getRidOfInvestment</span><span style="font-size: 11pt">取代了。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std::tr1::shared_ptr&lt; Investment &gt; </span></p>
<p style="margin: 0cm 0cm 0pt 21.3pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">pInv(static_cast&lt;Investment*&gt;(0), getRidOfInvestment);</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">那么定义就应该是这样的：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std::tr1::shared_ptr&lt; Investment &gt; createInvestment()</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">{</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&nbsp;&nbsp; std::tr1::shared_ptr&lt; Investment &gt; </span></p>
<p style="margin: 0cm 0cm 0pt 21.3pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">retVal(static_cast&lt;Investment*&gt;(0), getRidOfInvestment); <span style="color: red">//</span></span><span style="font-size: 11pt; color: red">这不能让</span><span style="font-size: 11pt; color: red; font-family: 'Arial','sans-serif'">client</span><span style="font-size: 11pt; color: red">来做</span></p>
<p style="margin: 0cm 0cm 0pt 7.1pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">retVal = </span><span style="font-size: 11pt">&#8230;</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">;</span></p>
<p style="margin: 0cm 0cm 0pt 7.1pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">return retVal;</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">}</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">tr1::shared_ptr</span><span style="font-size: 11pt">的优点是允许在一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">DLL</span><span style="font-size: 11pt">创建对象，在另一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">DLL</span><span style="font-size: 11pt">里删除对象。</span></p>
<h2><span style="font-family: 新宋体">牢记</span></h2>
<ul style="margin-top: 0cm" type="disc">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Good interfaces are easy to use correctly and hard to use in correctly.</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">接口一致性，于内置数据类型的行为兼容</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">阻止错误的方式还包括创建新的类型（例如</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Month</span><span style="font-size: 11pt">），限制类型上的操作，束缚对象值，以及消除客户的资源管理的责任</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">tr1::shared_ptr</span><span style="font-size: 11pt">支持定制类型的删除器</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">deleter</span><span style="font-size: 11pt">，允许在一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">DLL</span><span style="font-size: 11pt">创建对象，在另一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">DLL</span><span style="font-size: 11pt">里删除对象。</span></li>
</ul>
<h1>Item19<span style="font-family: 宋体">：</span>Treat class design as type design.<span style="font-family: 宋体">设计</span>class<span style="font-family: 宋体">犹如设计</span>type </h1>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">在设计一个类的时候，要回答一系列的问题哦。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">参考大师在</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">P85-P86</span><span style="font-size: 11pt">之间给出的常常的清单吧，其实实际上，我在设计类的时候的确没有想过这么多，问过自己这么的为什么，所以这也是我总是在追求代码重用，却总是发现自己写的代码重用度很低的一个原因把。</span></p>
<h1>Item20<span style="font-family: 宋体">：</span>Prefer pass-by-reference-to-const to pass-by-value.<span style="font-family: 宋体">宁以</span>pass-by-reference-to-const<span style="font-family: 宋体">替换</span>pass-by-value </h1>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; color: #993300; font-family: 'Arial','sans-serif'">But</span><span style="font-size: 11pt; color: #993300">先学习一个单词，</span><span style="font-size: 11pt; color: #993300; font-family: 'Arial','sans-serif'">characteristic</span><span style="font-size: 11pt; color: #993300">，</span><span style="font-size: 11pt; color: #993300; font-family: 'Arial','sans-serif'">KAO</span><span style="font-size: 11pt; color: #993300">，这竟然是个名词。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; color: #993300">再学一个地道的说法：解决问题的方法：</span><u><span style="font-size: 11pt; color: #993300; font-family: 'Arial','sans-serif'">The way around the slicing problem is&#8230;</span></u></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">函数都是值传递。</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">pass by-value</span><span style="font-size: 11pt">。</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">function parameters are initialized with copies of the actual arguments, and function callers goes back a copy of the value returned by the function.</span><span style="font-size: 11pt">这样当然开销就大了，每次都先</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">copy</span><span style="font-size: 11pt">一份进来，完事以后，再</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">copy</span><span style="font-size: 11pt">一份出去。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">假设函数的参数是一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Student</span><span style="font-size: 11pt">对象，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">bool validateStudent(Student s);</span><span style="font-size: 11pt">调用这个函数，<u><span style="color: blue">额外的隐性开销包括要先调用</span></u></span><u><span style="font-size: 11pt; color: blue; font-family: 'Arial','sans-serif'">copy constructor</span></u><u><span style="font-size: 11pt; color: blue">创建一个</span></u><u><span style="font-size: 11pt; color: blue; font-family: 'Arial','sans-serif'">Student</span></u><u><span style="font-size: 11pt; color: blue">对象用于函数内部，函数执行结束再调用析构函数释放这个对象。</span></u></p>
<h3><span style="font-family: 宋体">开销太大了，改进一下：</span>pass by reference-to-const</h3>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">bool validateStudent(<strong>const</strong> Student<strong>&amp;</strong> s);</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; color: red">引用是通过指针来实现实现的，因此传递引用实际上就是在传递指针。</span><span style="font-size: 11pt; color: red; font-family: 'Arial','sans-serif'">references are typically implemented as pointers.</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">但是这个规则对于内置数据类型不适用，也不是适用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">STL iterator</span><span style="font-size: 11pt">和函数对象</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">function objects</span><span style="font-size: 11pt">。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">即使再小的对象也应该不要使用值传递，而是要使用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">pass by reference-to-const</span><span style="font-size: 11pt">。</span></p>
<h3><span style="font-family: 宋体">关于</span>slicing problem<span style="font-family: 宋体">的另一种描述</span></h3>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">slicing problem</span><span style="font-size: 11pt">是在多态规则里面容易产生的。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">看一个简单的基类、派生类的定义</span></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">class Window </span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">{</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">public:</span></em></p>
<p style="margin: 0cm 0cm 0pt 7.1pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">int height;</span></em></p>
<p style="margin: 0cm 0cm 0pt 7.1pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">int width;</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">};</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">class TextWindow : public Window</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">{</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">public:</span></em></p>
<p style="margin: 0cm 0cm 0pt 7.1pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">int cursorLocation;</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">};</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0">&#8230;</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">Window win;</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">TextWindow *tWinPtr;</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">tWinPtr = new TextWindow;</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">win = *tWinprt;</span></em></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">win</span><span style="font-size: 11pt">是一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Window</span><span style="font-size: 11pt">对象，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">C++</span><span style="font-size: 11pt">规定：给</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">win</span><span style="font-size: 11pt">分配的内存看见的大小，由其静态类型决定。就是说默认的拷贝函数导致信息会出现丢失。这就是</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">slicing problem</span><span style="font-size: 11pt">。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">试想一下这要是通过值传递的方式传递参数，实参一</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">copy</span><span style="font-size: 11pt">就已经丢失信息了。</span></p>
<h2><span style="font-family: 新宋体">牢记</span></h2>
<ul style="margin-top: 0cm" type="disc">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Prefer pass-by-reference-to-const over pass-by-value.</span><span style="font-size: 11pt">这样既有效，又可以避免</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">slicing problem</span><span style="font-size: 11pt">。</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">但是这个规则对于内置数据类型，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">STL iterator</span><span style="font-size: 11pt">和函数对象</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">function objects</span><span style="font-size: 11pt">不适用。对于它们传递值就好了。</span></li>
</ul>
<h1>Item 21<span style="font-family: 宋体">：</span>Don't try to return a reference when you must return an object.<span style="font-family: 宋体">必须返回对象时，别妄想返回其</span>reference </h1>
<h2>heap and stack</h2>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">堆和栈这是</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">2</span><span style="font-size: 11pt">个不同的概念，哎哟，我一直以为是一个词。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">heap</span><span style="font-size: 11pt">：堆</span></p>
<ul style="margin-top: 0cm" type="disc">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">栈是系统提供的功能，特点是快速高效，缺点是有限制，数据不灵活；</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">堆是函数库内部数据结构，不一定唯一。</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">堆空间的分配总是动态的，虽然程序结束时所有的数据空间都会被释放回系统，但是精确的申请内存</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">/</span><span style="font-size: 11pt">释放内存匹配是良好程序的基本要素。</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">使用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">new</span><span style="font-size: 11pt">创建的对象是在</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">heap</span><span style="font-size: 11pt">上分配内存空间。</span></li>
</ul>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">stack</span><span style="font-size: 11pt">：栈</span></p>
<ul style="margin-top: 0cm" type="disc">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">而堆是函数库提供的功能，特点是灵活方便，数据适应面广泛，但是效率有一定降低。</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">栈是系统数据结构，对于进程</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">/</span><span style="font-size: 11pt">线程是唯一的；不同堆分配的内存无法互相操作。</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">栈空间分静态分配和动态分配两种。静态分配是编译器完成的，比如自动变量</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">(auto)</span><span style="font-size: 11pt">的分配。动态分配由</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">alloca</span><span style="font-size: 11pt">函数完成。栈的动态分配无需释放</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">(</span><span style="font-size: 11pt">是自动的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">)</span><span style="font-size: 11pt">，也就没有释放函数。为可移植的程序起见，<u>栈的动态分配操作是不被鼓励的！</u></span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">定义的局部变量是在</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">stack</span><span style="font-size: 11pt">上分配内存空间的。</span></li>
</ul>
<h2><span style="font-family: 新宋体">牢记</span></h2>
<ul style="margin-top: 0cm" type="disc">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">简单一句话就是必须要返回对象。</span></li>
</ul>
<h1>Item22<span style="font-family: 宋体">：</span>Declare data members private.<span style="font-family: 宋体">将成员变量声明为</span>private </h1>
<h2>why data members shouldn&#8217;t be public?</h2>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">argument</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">(against) </span><span style="font-size: 11pt">争论，意见</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt">实参</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt">形参是</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">parameters</span></p>
<h2>protected data member is mot more encapsulated than public one.</h2>
<h2><span style="font-family: 新宋体">牢记</span></h2>
<ul style="margin-top: 0cm" type="disc">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">data member</span><span style="font-size: 11pt">一定要封装。</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">protected</span><span style="font-size: 11pt">不必</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">public</span><span style="font-size: 11pt">有更好的封装。</span></li>
</ul>
<h1>Item 23<span style="font-family: 宋体">：</span>Prefer non-member non-friend functions to member functions.<span style="font-family: 宋体">宁以</span>non-member<span style="font-family: 宋体">、</span>non-friend<span style="font-family: 宋体">替换</span>member<span style="font-family: 宋体">函数</span></h1>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">这是一个典型的例子：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">class WebBrowser {</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">public:</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&#8230;</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">void clearCache();</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">void clearHistory();</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">void removeCookies();</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&#8230;</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">};</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">为了提供一个执行所有操作的函数，所以就在</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">WebBrowser</span><span style="font-size: 11pt">里面追加定义：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">void clearEverything();</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">哎，我一直就是这么写的，并自以为有很好的封装，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">But</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">void clearBrowser(WebBrowser wb) </span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">{</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">wb.clearCache();</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">wb.clearHistory();</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">wb.removeCookies();</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">}</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">第一：前者并不比后者有很好的封装</span></p>
<p style="margin: 0cm 0cm 0pt 21.3pt"><span style="font-size: 11pt">这就要解释一下什么叫做&#8220;封装&#8221;？以及封装的判别标准。</span></p>
<p style="margin: 0cm 0cm 0pt 21.3pt"><span style="font-size: 11pt">封装的判别标准：可以通过统计能够访问这个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">data</span><span style="font-size: 11pt">的函数的数目来计算，函数越多，这个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">data</span><span style="font-size: 11pt">封装也就月不好，因此前一种写法的封装就没有后者好。这也可以用来解释</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Item22</span><span style="font-size: 11pt">里面，为什么要求数据成员不能定义为</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">public</span><span style="font-size: 11pt">。另外增加</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">clearEverything()</span><span style="font-size: 11pt">作为</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">member function</span><span style="font-size: 11pt">，实际上是降低了封装性。而后面的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">non-member non-friend functions</span><span style="font-size: 11pt">的定义就没有改变</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">WebBrowser</span><span style="font-size: 11pt">的封装性。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">第二：后者还能提供更加灵活的打包</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">package</span><span style="font-size: 11pt">，增加扩展性。</span></p>
<p style="margin: 0cm 0cm 0pt 21.3pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">put all convenience functions in multiple header files, but one namespace.</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">第三：增加函数的可扩展性。</span></p>
<p style="margin: 0cm 0cm 0pt 21.3pt"><span style="font-size: 11pt">你可以定义自己的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">convenience functions</span><span style="font-size: 11pt">，写到一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">header file</span><span style="font-size: 11pt">里面，放到同一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">namespace</span><span style="font-size: 11pt">里面。这是</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">member function</span><span style="font-size: 11pt">做不到的。</span></p>
<h2><span style="font-family: 新宋体">牢记</span></h2>
<ul style="margin-top: 0cm" type="disc">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt">优先使用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">non-member non-friend</span><span style="font-size: 11pt">函数来替换</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">member</span><span style="font-size: 11pt">函数。</span></li>
</ul>
<h1>Item 24<span style="font-family: 宋体">：</span>Declare non-member functions when type conversions should apply to all parameters.<span style="font-family: 宋体">若所有参数皆需类型转换，请为此采用</span>non-member<span style="font-family: 宋体">函数</span></h1>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">原因：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Parameters are eligible for implicit type conversion only if they are listed in the parameter list.</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">结论：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">make operator* a non-member function, thus allowing compilers to perform implicit type conversions on all arguments.</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">class Rational {</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">&#8230;</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">};</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">const Rational operatior*(const Rational&amp; lhs, Rational&amp; rhs) </span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">{</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&nbsp;&nbsp; return Rationan(lhs.numerator()*rhs.numerator(),</span></p>
<p style="margin: 0cm 0cm 0pt 36pt; text-indent: 36pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">lhs.denominator()*rhs. denominator () );</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">}</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">一个误区：</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">如果一个函数，和某个类相关，而又不能定义成</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">member</span><span style="font-size: 11pt">，那么这个函数就一定要定义成</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">friend</span><span style="font-size: 11pt">。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">上面这个例子就说明这个说法并不正确。真爱生命，慎用</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">friend functions</span><span style="font-size: 11pt">。</span></p>
<h1>Item 25<span style="font-family: 宋体">：</span>Consider support for a non-throwing swap.<span style="font-family: 宋体">考虑写出一个不抛异常的</span>swap<span style="font-family: 宋体">函数</span></h1>
<ol style="margin-top: 0cm" type="1">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">default swap</span></li>
</ol>
<p style="margin: 0cm 0cm 0pt 35.45pt"><span style="font-size: 11pt">就是指</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std</span><span style="font-size: 11pt">里面定义的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">swap</span></p>
<ol style="margin-top: 0cm" type="1" start="2">
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">member swap</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">nonmember swap</span></li>
    <li style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">specializations of std::swap</span></li>
</ol>
<h2>member swap</h2>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Widget</span><span style="font-size: 11pt">：</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">:</span><span style="font-size: 11pt">我们希望的是交换指针，但</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">swap</span><span style="font-size: 11pt">实际做的是不仅</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">copy</span><span style="font-size: 11pt">了</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">3</span><span style="font-size: 11pt">个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Widget</span><span style="font-size: 11pt">对象，而且还</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">copy</span><span style="font-size: 11pt">了</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">3</span><span style="font-size: 11pt">个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">WidgetImpl</span><span style="font-size: 11pt">对象。太浪费了！都低碳时代了。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">class&nbsp;Widget{</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">void swap(Widget&amp; other)</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">{</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">using std::swap;</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">swap(pImpl, other.pImpl;);</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">}</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&#8230;</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">};</span></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">template&lt;&gt; void swap&lt;Widget&gt;( Widget&amp; a, Widget&amp;b)</span></em></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">{</span></em></p>
<p style="margin-bottom: 0pt"><strong><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">&nbsp;&nbsp; a.wap(b);</span></em></strong></p>
<p style="margin-bottom: 0pt"><em><span style="font-size: 11pt; color: #0070c0; font-family: 'Arial','sans-serif'">}</span></em></p>
<h2>nonmember swap</h2>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">接下来要讨论的是如果</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">Widget</span><span style="font-size: 11pt">和</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">WidgetImpl</span><span style="font-size: 11pt">不是类而是类模板会怎么样？</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">约束条件：不能在</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std</span><span style="font-size: 11pt">里面增加新的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">template</span><span style="font-size: 11pt">，只能特化（</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">specialize</span><span style="font-size: 11pt">）</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std</span><span style="font-size: 11pt">内的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">template</span><span style="font-size: 11pt">。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">如果非要定义，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">say sorry</span><span style="font-size: 11pt">。</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">behavior is undefined</span><span style="font-size: 11pt">。</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">KAO</span><span style="font-size: 11pt">，其实这比异常还讨厌。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">解决方法是把它定义到一个自己的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">namespace</span><span style="font-size: 11pt">里面，而不要定义到</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std</span><span style="font-size: 11pt">里面。</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">namespace WidgetStuff {</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&#8230;</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">template&lt;typename T&gt;</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">class Widget{&#8230;};</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">&#8230;</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">template&lt;typename T&gt;</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">void swap(Widget&lt;T&gt;&amp; a, Widget&lt;T&gt;&amp; b)</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">{</span></p>
<p style="margin: 0cm 0cm 0pt 1cm"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">a.swap(b);</span></p>
<p style="margin: 0cm 0cm 0pt 14.2pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">}</span></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">}</span></p>
<h2>specializations of std::swap</h2>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">如果仅仅是针对一个</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">class</span><span style="font-size: 11pt">，那就特化</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">std::swap</span><span style="font-size: 11pt">。</span></p>
<p style="margin-bottom: 0pt"><u><span style="font-size: 11pt; color: #c00000; font-family: 'Arial','sans-serif'">If you want to have your class-specializing version of swap called in as many contexts as possible, you need to write both a non-member version in the same namespace as your class and a specialization of std::swap.</span></u></p>
<p style="margin-bottom: 0pt"><span style="font-size: 11pt">这部分十分绕，</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">P111</span><span style="font-size: 11pt">还对于</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">C++</span><span style="font-size: 11pt">的</span><span style="font-size: 11pt; font-family: 'Arial','sans-serif'">name lookup</span><span style="font-size: 11pt">的规则进行了详细的描述。值得重新温习。</span></p>
 <img src ="http://www.blogjava.net/amenglai/aggbug/316139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amenglai/" target="_blank">amenglai</a> 2010-03-22 11:28 <a href="http://www.blogjava.net/amenglai/articles/316139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Effecitive C++读书笔记 第五章 实现 Implementations</title><link>http://www.blogjava.net/amenglai/articles/316135.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Mon, 22 Mar 2010 03:19:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/316135.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/316135.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/316135.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/316135.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/316135.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Item26：Postpone variable definitions as long as possible.尽可能延后变量定义的出现时间这里所说的变量是variable of type，它需要调用constructor和destructor。简单情况下，如果函数抛出异常，导致变量没有被使用到，但是由于已经定义过，其实还是需要调用它的constructor和destru...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/316135.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/316135.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/amenglai/" target="_blank">amenglai</a> 2010-03-22 11:19 <a href="http://www.blogjava.net/amenglai/articles/316135.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>