??xml version="1.0" encoding="utf-8" standalone="yes"?>久久伊人精品青青草原高清,中文字幕成人精品久久不卡,国产精品久久国产精麻豆99网站http://www.shnenglu.com/richardzeng/category/1012.htmlVC++ 斚w~程文章zh-cnSat, 24 May 2008 16:07:24 GMTSat, 24 May 2008 16:07:24 GMT60EffectiveC++2ed 关于函数q回对象Q引用还是指?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Fri, 24 Mar 2006 07:51:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/4540.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/4540.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/4540.html</trackback:ping><description><![CDATA[ <h2> <font size="3">我看到EffectiveC++2ed中函数返回对象中的说明感觉以后再也不惌q回M东西啦。比较怕?/font> </h2> <p>但是有的时候不q回M东西是不行的ѝ?/p> <p>q回引用Q返回指针,q回对象到底怎么写?Q?br /><br />—————————————————————————————?br />下面是IQ中的内?/p> <h2>条款23: 必须q回一个对象时不要试图q回一个引?/h2> <p> </p> <p>据说爱因斯坦曾提q样的徏议:可能地让事情简单,但不要过于简单。在c++语言中相似的说法应该是:可能地使程序高效,但不要过于高效?/p> <p>一旦程序员抓住了“传值”在效率上的把柄Q参见条?2Q,他们会变得十分极端,恨不得挖出每一个隐藏在E序中的传值操作。岂不知Q在他们不懈地追求纯_的“传引用”的q程中,他们会不可避免地犯另一个严重的错误Q传递一个ƈ不存在的对象的引用。这׃是好事了?/p> <p>看一个表C有理数的类Q其中包含一个友元函敎ͼ用于两个有理数相乘:</p> <p>class rational {<br />public:<br />  rational(int numerator = 0, int denominator = 1);</p> <p>  ...</p> <p>private:<br />  int n, d;              // 分子和分?/p> <p>friend<br />  const rational                      // 参见条款21Qؓ什?br />    operator*(const rational& lhs,    // q回值是const<br />              const rational& rhs)     <br />};</p> <p>inline const rational operator*(const rational& lhs,<br />                                const rational& rhs)<br />{<br />  return rational(lhs.n * rhs.n, lhs.d * rhs.d);<br />}</p> <p>很明显,q个版本的operator*是通过传D回对象结果,如果不去考虑对象构造和析构时的开销Q你是在逃避作ؓ一个程序员的责仅R另外一件很明显的事实是Q除非确实有必要Q否则谁都不愿意承担q样一个时对象的开销。那么,问题归l于Q确实有必要吗?</p> <p>{案是,如果能返回一个引用,当然没有必要。但误住,引用只是一个名字,一个其它某个已l存在的对象的名字。无Z时看C个引用的声明Q就要立即问自己Q它的另一个名字是什么呢Q因为它必然q有另外一个什么名字(见条ƾm1Q。拿operator*来说Q如果函数要q回一个引用,那它q回的必L其它某个已经存在的rational对象的引用,q个对象包含了两个对象相乘的l果?/p> <p>但,期望在调用operator*之前有这样一个对象存在是没道理的。也是_如果有下面的代码Q?/p> <p>rational a(1, 2);                // a = 1/2<br />rational b(3, 5);                // b = 3/5<br />rational c = a * b;              // c ?3/10</p> <p>期望已经存在一个gؓ3/10的有理数是不现实的。如果operator* 一定要q回q样一个数的引用,必自己创个数的对象?/p> <p>一个函数只能有两种Ҏ创徏一个新对象Q在堆栈里或在堆上。在堆栈里创建对象时伴随着一个局部变量的定义Q采用这U方法,pq样写operator*Q?/p> <p>// 写此函数的第一个错误方?br />inline const rational& operator*(const rational& lhs,<br />                                 const rational& rhs)<br />{<br />  rational result(lhs.n * rhs.n, lhs.d * rhs.d);<br />  return result;<br />}</p> <p>q个Ҏ应该被否冻I因ؓ我们的目标是避免构造函数被调用Q但result必须要象其它对象一栯构造。另外,q个函数q有另外一个更严重的问题,它返回的是一个局部对象的引用Q关于这个错误,条款31q行了深入的讨论?/p> <p>那么Q在堆上创徏一个对象然后返回它的引用呢Q基于堆的对象是通过使用new产生的,所以应该这样写operator*Q?/p> <p>// 写此函数的第二个错误Ҏ<br />inline const rational& operator*(const rational& lhs,<br />                                 const rational& rhs)<br />{<br />  rational *result =<br />    new rational(lhs.n * rhs.n, lhs.d * rhs.d);<br />  return *result;<br />}</p> <p>首先Q你q是得负担构造函数调用的开销Q因为new分配的内存是通过调用一个适当的构造函数来初始化的Q见条款5和m8Q。另外,q有一个问题:谁将负责用delete来删除掉new生成的对象呢Q?/p> <p>实际上,q绝Ҏ一个内存泄漏。即使可以说服operator*的调用者去取函数返回值地址Q然后用deleted除它Q绝对不可能——条?1展示了这L代码会是什么样的)Q但一些复杂的表达式会产生没有名字的时|E序员是不可能得到的。例如:</p> <p>rational w, x, y, z;</p> <p>w = x * y * z;</p> <p>两个对operator*的调用都产生了没有名字的临时|E序员无法看刎ͼ因而无法删除。(再次参见条款31Q?/p> <p>也许Q你会想你比一般的熊——或一般的E序员——要聪明Q也许,你注意到在堆栈和堆上创徏对象的方法避免不了对构造函数的调用Q也许,你想起了我们最初的目标是ؓ了避免这U对构造函数的调用Q也许,你有个办法可以只用一个构造函数来搞掂一切;也许Q你的眼前出Cq样一D代码:operator*q回一个“在函数内部定义的静态rational对象”的引用Q?/p> <p>// 写此函数的第三个错误Ҏ<br />inline const rational& operator*(const rational& lhs,<br />                                 const rational& rhs)<br />{<br />  static rational result;      // 要作ؓ引用q回?br />                               // 静态对?/p> <p>  lhs和rhs 怹Q结果放qresultQ?/p> <p>  return result;<br />}</p> <p>q个Ҏ看v来好象有戏,虽然在实际实C面的伪代码时你会发现Q不调用一个rational构造函数是不可能给出result的正值的Q而避免这L调用正是我们要谈论的主题。就你实现了上面的伪代码,但,你再聪明也不能最l挽救这个不q的设计?/p> <p>想知道ؓ什么,看看下面q段写得很合理的用户代码Q?/p> <p>bool operator==(const rational& lhs,      // rationals的operator==<br />                const rational& rhs);     // </p> <p>rational a, b, c, d;</p> <p>...</p> <p>if ((a * b) == (c * d)) {</p> <p>  处理相等的情?</p> <p>} else {</p> <p>  处理不相{的情况;</p> <p>}</p> <p>看出来了吗?((a*b) == (c*d)) 会永qؓtrueQ不aQbQc和d是什么|</p> <p>用等L函数形式重写上面的相{判断语句就很容易明白发生这一可恶行ؓ的原因了Q?/p> <p>if (operator==(operator*(a, b), operator*(c, d)))</p> <p>注意当operator==被调用时QL两个operator*刚被调用Q每个调用返回operator*内部的静态rational对象的引用。于是,上面的语句实际上是请求operator==对“operator*内部的静态rational对象的值”和“operator*内部的静态rational对象的值”进行比较,q样的比较不相等才怪呢Q?/p> <p>q运的话Q我以上的说明应该以说服你Q想“在象operator*q样的函数里q回一个引用”实际上是在费旉。但我没q稚C怿q运M光自己。一些h——你们知道这些h是指谁——此M在想Q“唔Q上面那个方法,如果一个静态变量不够用Q也许可以用一个静态数l……?/p> <p>请就此打住!我们Nq没受够吗?</p> <p>我不能让自己写一D늤例代码来太高q个设计Q因为即使只抱有上面q种x都以o人感到羞愧。首先,你必选择一个nQ指定数l的大小。如果n太小Q就会没地方储存函数q回|q和我们前面否定的那个“采用单个静态变量的设计”相比没有什么改q。如果n太大Q就会降低程序的性能Q因为函数第一ơ被调用时数l中每个对象都要被创建。这会带来n个构造函数和n个析构函数的开销Q即使这个函数只被调用一ơ。如果说"optimization"Q最优化Q是指提高Y件的性能的过E, 那么现在q种做法直可以称?pessimization"Q最差化Q。最后,x怎么把需要的值放到数l的对象中以及需要多大的开销Q在对象间传值的最直接的方法是通过赋|但赋值的开销又有多大呢?一般来_它相当于调用一个析构函敎ͼ摧毁旧|再加上调用一个构造函敎ͼ拯新|。但我们现在的目标正是ؓ了避免构造和析构的开销啊!面对现实吧:q个Ҏ也绝对不能选用?/p> <p>所以,写一个必返回一个新对象的函数的正确Ҏ是让这个函数返回一个新对象。对于rational的operator*来说Q这意味着要不是下面的代码(是最初看到的那段代码Q,要不是本质上和它等L代码Q?/p> <p>inline const rational operator*(const rational& lhs,<br />                                const rational& rhs)<br />{<br />  return rational(lhs.n * rhs.n, lhs.d * rhs.d);<br />}</p> <p>的确Q这会导致“operator*的返回值构造和析构时带来的开销”,但归根结底它只是用小的代h来正的E序q行行ؓ而已。况且,你所担心的开销q有可能永远不会出现Q和所有程序设计语a一Pc++允许~译器的设计者采用一些优化措施来提高所生成的代码的性能Q所以,在有些场合,operator*的返回g被安全地除去Q见条款m20Q。当~译器采用了q种优化Ӟ当前大部分编译器q么做)Q程序和以前一Ll工作,只不q是q行速度比你预计的要快而已?/p> <p>以上讨论可以归结为:当需要在q回引用和返回对象间做决定时Q你的职责是选择可以完成正确功能的那个。至于怎么让这个选择所产生的代价尽可能的小Q那是编译器的生产商L的事?/p> <img src ="http://www.shnenglu.com/richardzeng/aggbug/4540.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-03-24 15:51 <a href="http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Doxygen 源代码文自动生成器的用笔?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Thu, 23 Mar 2006 14:32:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/4508.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/4508.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/4508.html</trackback:ping><description><![CDATA[     摘要: ? google 上搜了很久的关于 Doxygen 使用Ҏ的咚咚,只不q都是英文,而且都很多的规则。实际上大家只需要告诉基本的规则可以。下面是我对 Doxygen 的摸?   首先熟知 Do...  <a href='http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html'>阅读全文</a><img src ="http://www.shnenglu.com/richardzeng/aggbug/4508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-03-23 22:32 <a href="http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的职业http://www.shnenglu.com/richardzeng/archive/2006/03/04/3719.htmlBeginning to ~程Beginning to ~程Sat, 04 Mar 2006 11:17:00 GMThttp://www.shnenglu.com/richardzeng/archive/2006/03/04/3719.htmlhttp://www.shnenglu.com/richardzeng/comments/3719.htmlhttp://www.shnenglu.com/richardzeng/archive/2006/03/04/3719.html#Feedback0http://www.shnenglu.com/richardzeng/comments/commentRss/3719.htmlhttp://www.shnenglu.com/richardzeng/services/trackbacks/3719.htmldq家公司后感?l于感觉又长大拉,也又老拉.

之后来到一家外资公?q不?也没有什么可忙的.
惛_自己一直想~个Y?服装l图斚w)?前一D|?BR>比较?现在可以静心下来学习一下基本理?徏立了q个Blog
也学学时髦吧.

今年1月我奛_生拉,真挺高兴?



Beginning to ~程 2006-03-04 19:17 发表评论
]]>
vaþþþͬ| þۺϾɫۺϾ99| Ұ¾þ| ɫþ| þþþþþþòҰ߳| þþ㽶ۺϼձ| 97rþþƷ99| 99þùһ| þþĻ| պAVþһ| ˾þ91| ޾ƷþþþĻ| þþþþAVר| պŷ޹ƷĻþþ| ޾Ʒ׽þþþþ| Ļ˾Ʒþò| þþƷAV| 99þùۺϾƷӰԺ| þþþav| Ʒ99þþþþwww| ޹Ʒþ98| þþĻ| 91þó| þݺҹҹվ| һþöۺ | 91Ʒ91þþþþ| ھƷþþþӰԺ| þ99Ʒ鶹ѿ| ˾þˬ| þþƷަvDz| ҹƷþþþþž| þþƷëƬѹۿ| ۺ޾þһƷ| þþþùAV鶹| 91þø˾Ʒ| 99þþƷѿ| þþþþþ99Ʒѹۿ| ŷպľþ| 볬鱬Ļþ| ݺۺϾþAVһ| þþþþþƷͼƬ|