﻿<?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-赖猫的学习笔记-文章分类-C++ Primer 之 读书笔记</title><link>http://www.blogjava.net/amenglai/category/37871.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 29 Aug 2009 04:08:16 GMT</lastBuildDate><pubDate>Sat, 29 Aug 2009 04:08:16 GMT</pubDate><ttl>60</ttl><item><title>C++ primer 读后感</title><link>http://www.blogjava.net/amenglai/articles/292922.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Fri, 28 Aug 2009 00:37:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/292922.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/292922.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/292922.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/292922.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/292922.html</trackback:ping><description><![CDATA[&nbsp;
<p style="text-indent: 36pt"><span style="font-family: 宋体">到今天，终于把&#8220;</span>C++ primer<span style="font-family: 宋体">&#8221;读完了。花了</span>4<span style="font-family: 宋体">个月的时间。千言万语，但是不知从何说起。一句话吧，这是一本很值得读的书，不管你是</span>Java<span style="font-family: 宋体">程序员还是</span>C++<span style="font-family: 宋体">程序员或者是</span>.Net<span style="font-family: 宋体">程序员。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">为什么？因为这是一次方法论的学习过程，而不仅仅是一种语言的学习。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">读着本书，按郭德纲的话说，得有过日子的心，就一页一页读下去，体会，反省，动手练习。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">具体到我，我看的是英文第四版，用的编译器是</span>MinGW<span style="font-family: 宋体">。这本书不仅可以学习</span>C++<span style="font-family: 宋体">，也是一本很好的学习英语的教材。英语很地道，而且对于词汇量的要求也不是很高（相对</span>Martin<span style="font-family: 宋体">大叔的书来说）。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">之所以选择</span>MinGW<span style="font-family: 宋体">只是因为它&#8220;轻&#8221;，因为我平时主要是用</span>Java<span style="font-family: 宋体">和</span>C<span style="font-family: 宋体">，其实工作中是没啥机会使用</span>C++<span style="font-family: 宋体">的。为了把主要精力放在</span>C++<span style="font-family: 宋体">本身，所以并没有用</span>VC<span style="font-family: 宋体">之类庞大的</span>IDE<span style="font-family: 宋体">工具。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">我看书的进度的确不算快，只有周一到周五这</span>5<span style="font-family: 宋体">天，周六、周日都用在和</span>huohuo<span style="font-family: 宋体">鬼混上，基本上没啥精力看书了。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">在看&#8220;</span>C++ primer<span style="font-family: 宋体">&#8221;的这</span>4<span style="font-family: 宋体">个月的时间里我还在业余时间里做了两个小项目。所以看书的时间并不是很规律。但是我的经验就是坚持。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">我很享受这</span>4<span style="font-family: 宋体">个月的时光。有时，我觉得这书咋像小说一样好看呢，上下班的路上，我都想下一页大师会讲些啥呢？有时，写着写着</span>java,<span style="font-family: 宋体">甚至有些恍惚，偶尔想，这要是</span>C++<span style="font-family: 宋体">多好，可以这样这样写了。</span></p>
<p style="text-indent: 36pt"><span style="font-family: 宋体">感谢</span>Lippman<span style="font-family: 宋体">，带给我的快乐。</span>Bye-Bye<span style="font-family: 宋体">。</span></p>
 <img src ="http://www.blogjava.net/amenglai/aggbug/292922.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> 2009-08-28 08:37 <a href="http://www.blogjava.net/amenglai/articles/292922.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十八章 特殊工具与技术</title><link>http://www.blogjava.net/amenglai/articles/292921.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Fri, 28 Aug 2009 00:35:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/292921.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/292921.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/292921.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/292921.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/292921.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Chapter 18. 特殊工具与技术&nbsp;18.1 优化内存分配Optimizing Memory Allocation分配内存和创建对象是两个不同的概念。分配内存，并不一定会立即创建对象。同样，内存释放和对象撤销也是两个不同的概念。&nbsp;18.1.1. C++ 中的内存分配new操作：给指定的类型分配内存并在新分配的内存上构造指定类型的对象。...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/292921.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/292921.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> 2009-08-28 08:35 <a href="http://www.blogjava.net/amenglai/articles/292921.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十七章 用于大型程序的工具</title><link>http://www.blogjava.net/amenglai/articles/290772.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 12 Aug 2009 03:10:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/290772.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/290772.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/290772.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/290772.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/290772.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;第十七章 Tools for Large Programs 用于大型程序的工具这一章值得仔细品味。17.1 异常处理（Exception Handling）C++异常处理包括：1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw 表达式（throw expressions）, throw 引发了异常条件。a throw raises an e...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/290772.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/290772.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> 2009-08-12 11:10 <a href="http://www.blogjava.net/amenglai/articles/290772.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十六章 模板和泛型编程</title><link>http://www.blogjava.net/amenglai/articles/288775.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Tue, 28 Jul 2009 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/288775.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/288775.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/288775.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/288775.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/288775.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;第十六章模板和泛型编程在C++中模板是泛型编程的基础。（In C++, templates are the foundation for generic programming.）16.1 模板定义Template Definitions16.1.1 定义函数模板 Defining a Function Template 函数模板是和类型无关的函数定义，它被当作是公...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/288775.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/288775.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> 2009-07-28 17:29 <a href="http://www.blogjava.net/amenglai/articles/288775.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十五章 面向对象编程</title><link>http://www.blogjava.net/amenglai/articles/286900.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 15 Jul 2009 08:36:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/286900.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/286900.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/286900.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/286900.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/286900.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Chap 15 Object-Oriented Programming 15.1 OOP总览继承inheritance hierarchy动态绑定在C++里，当虚函数通过基类的引用或者指针被调用时，就会发生动态绑定。（In C++, dynamic binding happens when a virtual function is called through...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/286900.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/286900.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> 2009-07-15 16:36 <a href="http://www.blogjava.net/amenglai/articles/286900.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十四章</title><link>http://www.blogjava.net/amenglai/articles/284866.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 01 Jul 2009 00:33:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/284866.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/284866.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/284866.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/284866.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/284866.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Overloaded Operations and Conversions (重载操作和转换)14.1 定义重载操作符（Defining an Overload Operators）重载操作符必须至少有一个操作数的类型是类。重载操作符必须至少有一个操作数是类类型和枚举类型。（An overloaded operator must have at least one ...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/284866.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/284866.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> 2009-07-01 08:33 <a href="http://www.blogjava.net/amenglai/articles/284866.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十三章</title><link>http://www.blogjava.net/amenglai/articles/283855.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 24 Jun 2009 00:17:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/283855.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/283855.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/283855.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/283855.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/283855.html</trackback:ping><description><![CDATA[&nbsp;
<p style="text-align: center" align="center"><span style="font-size: 15pt; font-family: 'Arial','sans-serif'">Chapter 13. Copy Control</span></p>
<h2>13.1 The Copy Constructor</h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">首先，这真是一个有趣的命题。我老喜欢。这让我想起的是</span><span style="font-family: 'Arial','sans-serif'">Java</span><span style="font-family: 宋体">的</span><span style="font-family: 'Arial','sans-serif'">clone</span><span style="font-family: 宋体">。（写下这句话时我还没有看这一节，只是一个预感）</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">过瘾啊。（写下这句话时我刚刚读完这一节，还没有来得及整理笔记，理顺思路）</span></p>
<p><strong><span style="font-family: 宋体">什么叫做拷贝构造函数？</span></strong></p>
<p><span style="font-family: 宋体">拷贝构造函数有一个形参，并且这个形参是指向同一个类的对象的引用。（</span><span style="font-family: 'Arial','sans-serif'">The constructor that takes a single parameter that is a (usually const) reference to an object of the class type itself is called the copy constructor.</span><span style="font-family: 宋体">）</span></p>
<h3><span style="font-family: 宋体">对象定义的形式</span></h3>
<p><span style="font-family: 'Arial','sans-serif'">c++</span><span style="font-family: 宋体">支持两种形式的初始化：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: 'Arial','sans-serif'">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">直接初始化，使用初始化式（</span><span style="font-family: 'Arial','sans-serif'">initializer</span><span style="font-family: 宋体">），直接调用对应的构造函数。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: 'Arial','sans-serif'">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">拷贝初始化，使用</span><span style="font-family: 'Arial','sans-serif'">&#8217;=&#8217;</span><span style="font-family: 宋体">。先调用构造函数生成临时对象，然后再调用拷贝构造函数把临时对象拷贝到我们要创建的对象里。（</span><span style="font-family: 'Arial','sans-serif'">Copy-initialization first uses the indicated constructor to create a temporary object. It then uses the copy constructor to copy that temporary into the one we are creating</span><span style="font-family: 宋体">）</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">string null_book = "9-999-99999-9"; // copy-initialization</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">string empty_direct;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // direct-initialization </span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">对于类的对象，当指定单一的实参或者为了拷贝明确构建临时对象时，才能使用拷贝初始化。（</span><span style="font-family: 'Arial','sans-serif'">For objects of class type, copy-initialization can be used only when specifying a single argument or when we explicitly build a temporary object to copy.</span><span style="font-family: 宋体">）</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">ifstream file2 = "filename"; // error: copy constructor is private</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// This initialization is okay only if</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// the Sales_item(const string&amp;) constructor is not explicit</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">Sales_item item = string("9-999-99999-9");</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">额外唠唠</span><em><span style="font-family: 'Arial','sans-serif'">Sales_item item = string("9-999-99999-9");</span></em></p>
<p style="margin-left: 27pt"><span style="font-family: 宋体">只有当</span><span style="font-family: 'Arial','sans-serif'">Sales_item</span><span style="font-family: 宋体">的构造函数中没有把</span><em><span style="font-family: 'Arial','sans-serif'">Sales_item(const string&amp;)</span></em><span style="font-family: 宋体">这个构造函数声明为</span><span style="font-family: 'Arial','sans-serif'">explicit</span><span style="font-family: 宋体">时，这个初始化才正确。这其中包含了一个隐式的类型转换：由实参</span><em><span style="font-family: 'Arial','sans-serif'">string("9-999-99999-9");</span></em><span style="font-family: 宋体">生成</span><span style="font-family: 'Arial','sans-serif'">Sales_item</span><span style="font-family: 宋体">类型的对象，然后再调用</span><span style="font-family: 'Arial','sans-serif'">copy</span><span style="font-family: 宋体">函数拷贝给</span><span style="font-family: 'Arial','sans-serif'">item</span><span style="font-family: 宋体">。</span></p>
<p style="margin-left: 27pt"><span style="font-family: 宋体">但是（咋这么多但是呢）如果这么写</span><em><span style="font-family: 'Arial','sans-serif'">Sales_item item2 = item;</span></em><span style="font-family: 宋体">就又不一样了。这样就变成了调用赋值操作符。</span></p>
<h3><span style="font-family: 宋体">合成复制构造函数</span></h3>
<p><span style="font-family: 宋体">复制构造函数是逐成员拷贝（</span><span style="font-family: 'Arial','sans-serif'">memberwise copy</span><span style="font-family: 宋体">）。</span></p>
<p><span style="font-family: 宋体">即使我们不能对</span><span style="font-family: 'Arial','sans-serif'">array</span><span style="font-family: 宋体">进行</span><span style="font-family: 'Arial','sans-serif'">copy</span><span style="font-family: 宋体">，但是如果一个类包含有数组类型的成员，合成的复制构造函数也会拷贝这个的数组。数组中的每个元素都会进行复制。（</span><span style="font-family: 'Arial','sans-serif'">Even though we ordinarily cannot copy an array, if a class has a member that is an array, then the synthesized copy constructor will copy the array.</span> <span style="font-family: 'Arial','sans-serif'">does so by copying each element.</span><span style="font-family: 宋体">）</span></p>
<h3><span style="font-family: 宋体">自定义拷贝函数</span></h3>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">class Foo {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Foo();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // default constructor</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Foo(const Foo&amp;); // copy constructor</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ...</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; };</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h3><span style="font-family: 宋体">阻止拷贝</span></h3>
<p><strong><span style="font-family: 宋体">方法：</span></strong><span style="font-family: 宋体">就是把拷贝函数声明为</span><span style="font-family: 'Arial','sans-serif'">private</span><span style="font-family: 宋体">。</span></p>
<h3><span style="font-family: 宋体">大多数类都应该定义拷贝构造函数和默认构造函数。</span></h3>
<p><span style="font-family: 宋体">如果一个类里面定义了一个构造函数，编译期就不会再为这个类生成默认构造函数，而需要自己来定义了。</span></p>
<p><span style="font-family: 宋体">温习一下什么是默认构造函数：（唉，忘记的真快啊）</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">默认构造函数没有形参。如果定义的对象不提供初始化式（</span><span style="font-family: 'Arial','sans-serif'">initializer</span><span style="font-family: 宋体">）就会调用默认构造函数。（</span><span style="font-family: 'Arial','sans-serif'">The default constructor is used whenever we define an object but do not supply an initializer.</span><span style="font-family: 宋体">）</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如果一个构造函数为所有形参提供缺省的实参，也可以叫做是默认构造函数。（</span><span style="font-family: 'Arial','sans-serif'">A constructor that supplies default arguments for all its parameters also defines the default constructor.</span><span style="font-family: 宋体">）</span></p>
<h2>13.2 The Assignment Operator</h2>
<p><span style="font-family: 宋体">如果类自己没有定义赋值操作符，那么编译器合成赋值操作符。（注意，这活是编译器干的）</span></p>
<h3><span style="font-family: 宋体">重载操作符（</span>overloaded operators<span style="font-family: 宋体">）</span></h3>
<p><span style="font-family: 宋体">操作符重载的形参列表（这里要包括</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">形参，如果操作符是成员函数的话）以及返回值必须和操作符所需要的操作数相同。</span></p>
<p><span style="font-family: 宋体">这句话咋理解呢？</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">Sales_item trans, accum;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">trans = accum;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 0cm; text-indent: 0cm"><span style="font-family: 'Arial','sans-serif'">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">形参列表</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">操作符</span><span style="font-family: 'Arial','sans-serif'">&#8217;=&#8217;</span><span style="font-family: 宋体">是二元操作符，它的操作数是两个：第一个操作数是左边的操作数，第二个操作数是右边的操作数。上面这个例子，如果我们需要重载</span><span style="font-family: 'Arial','sans-serif'">&#8217;=&#8217;</span><span style="font-family: 宋体">，第一个操作数是被绑定到</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">指针上，第二个操作数是一个</span><span style="font-family: 'Arial','sans-serif'">Sales_item</span><span style="font-family: 宋体">类型的对象一般来说，<strong>右边操作数一般都是作为</strong></span><strong><span style="font-family: 'Arial','sans-serif'">const</span></strong><strong><span style="font-family: 宋体">引用传递。</span></strong><span style="font-family: 宋体">（</span><span style="font-family: 'Arial','sans-serif'">Usually, the right-hand operand is passed as a const reference.</span><span style="font-family: 宋体">）。</span></p>
<p style="margin-left: 35.45pt"><em><span style="font-family: 'Arial','sans-serif'">Sales_item&amp; operator=(const Sales_item &amp;);</span></em></p>
<p style="margin-left: 0cm; text-indent: 0cm"><span style="font-family: 'Arial','sans-serif'">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">返回值</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">赋值操作符的返回值类型应该和内置类型的返回值类型相同。（</span><span style="font-family: 'Arial','sans-serif'">The return type from the assignment operator should be the same as the return from assignment for the built-in types</span><span style="font-family: 宋体">）内置类型的赋值返回的是左操作数的引用，因此赋值操作符也必须返回和它的类类型相同的引用。具体到</span><span style="font-family: 'Arial','sans-serif'">Sales_item</span><span style="font-family: 宋体">，</span><span style="font-family: 'Arial','sans-serif'">&#8217;=&#8217;</span><span style="font-family: 宋体">操作符重载的返回值是</span><span style="font-family: 'Arial','sans-serif'">Sales_item</span><span style="font-family: 宋体">的引用。</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">class Sales_item {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // other members as before</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // equivalent to the synthesized assignment operator</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sales_item&amp; operator=(const Sales_item &amp;);</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h3><span style="font-family: 宋体">合成赋值操作符</span></h3>
<p><span style="font-family: 宋体">合成赋值操作符也是逐个成员赋值（</span><span style="font-family: 'Arial','sans-serif'">memberwise assignment</span><span style="font-family: 宋体">）。对于数组是对每个元素进行赋值。</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">// equivalent to the synthesized assignment operator</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;Sales_item&amp;&nbsp;Sales_item::operator=(const Sales_item &amp;rhs)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;{</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isbn = rhs.isbn;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // calls string::operator=</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; units_sold = rhs.units_sold;&nbsp;// uses built-in int assignment</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; revenue = rhs.revenue;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // uses built-in double assignment</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return *this;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h2>13.3 The Destructor</h2>
<h3><span style="font-family: 宋体">什么时候调用析构函数？</span></h3>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">// p points to default constructed object</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; Sales_item *p = new Sales_item;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // new scope</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sales_item item(*p);&nbsp;// copy constructor copies *p into item</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // destructor called on object pointed to by p</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">以上这个例子说明在两种情况下会调用析构函数：</span></p>
<ol style="margin-top: 0cm" type="1">
    <li><span style="font-family: 宋体">当变量在作用域范围之外的时候，自动被撤销（</span><span style="font-family: 'Arial','sans-serif'">destroied</span><span style="font-family: 宋体">）</span></li>
    <li><span style="font-family: 宋体">指向对象的指针被删除（</span><span style="font-family: 'Arial','sans-serif'">deleted</span><span style="font-family: 宋体">），这个对象也就被撤销（</span><span style="font-family: 'Arial','sans-serif'">destroied</span><span style="font-family: 宋体">）</span></li>
</ol>
<p><span style="font-family: 宋体">进一步说明的是指向对象的指针或者是引用即使出了作用域，析构函数也是不会被执行的。就还是以上面的例子来说明：</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">// p points to default constructed object</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; Sales_item *p = new Sales_item;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;// new scope</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sales_item *ghost = new Sales_item;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Sales_item item(*p);&nbsp;// copy constructor copies *p into item</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // destructor called on object pointed to by p</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 'Arial','sans-serif'">ghost</span><span style="font-family: 宋体">这个小鬼即使出了作用域实际上也是没有被删除滴，占用的内存空间也是没有被释放滴。这样的程序跑上</span><span style="font-family: 'Arial','sans-serif'">N</span><span style="font-family: 宋体">遍，机器就会想老牛一样慢了。哎：（</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">另外当容器撤销时，容器中的元素的析构函数也会被调用（</span><span style="font-family: 'Arial','sans-serif'">Destructors are also run on the elements of class type in a container - whether a library container or built-in array - when the container is destroyed</span><span style="font-family: 宋体">）</span></p>
<h3><span style="font-family: 宋体">啥时需要写显式的析构函数</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">析构函数用来释放构造函数或对象生存周期内所需的资源</span><span style="font-family: 'Arial','sans-serif'">( Ordinarily they are used to relinquish resources acquired in the constructor or during the lifetime of the object.)</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">另外析构函数也不仅仅是用来释放资源。析构函数可以执行类设计者希望执行的任何操作，这些操作和类对象使用完毕之后执行。（</span><span style="font-family: 'Arial','sans-serif'">A destructor is not limited only to relinquishing resources. A destructor, in general, can perform any operation that the class designer wishes to have executed subsequent to the last use of an object of that class.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">首要原则是：如果类需要析构函数，那么它一定也需要拷贝构造函数（</span><span style="font-family: 'Arial','sans-serif'">copy constructor</span><span style="font-family: 宋体">）和赋值操作符（</span><span style="font-family: 'Arial','sans-serif'">assignment operator</span><span style="font-family: 宋体">）。</span></p>
<h3><span style="font-family: 宋体">合成析构函数</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">析构函数和拷贝构造函数（</span><span style="font-family: 'Arial','sans-serif'">copy constructor</span><span style="font-family: 宋体">）和赋值操作符（</span><span style="font-family: 'Arial','sans-serif'">assignment operator</span><span style="font-family: 宋体">）不同，就是即使你定义了自己的析构函数，当</span><span style="font-family: 'Arial','sans-serif'">delete</span><span style="font-family: 宋体">时，先调用你自己的析构函数，然后还是要调用合成的析构函数（</span><span style="font-family: 'Arial','sans-serif'">synthesized destructor</span><span style="font-family: 宋体">）。</span></p>
<p><span style="font-family: 宋体">析构函数执行的顺序：和构造函数恰恰相反。按照成员在类里面定义的相反的顺序撤销成员。（</span><span style="font-family: 'Arial','sans-serif'">it destroys the members in reverse order from which they are declared in the class. For each member that is of class type, the synthesized destructor invokes that member's destructor to destroy the object.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">自定义析构函数和合成析构函数的执行顺序：先自定义析构函数，然后再执行合成析构函数。</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">class Sales_item {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // empty; no work to do other than destroying the members,</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // which happens automatically</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~Sales_item() { }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // other members as before</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h2>13.4 A Message-Handling Example</h2>
<p><span style="font-family: 宋体">需求描述：</span></p>
<ol style="margin-top: 0cm" type="1">
    <li><span style="font-family: 宋体">新建</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">：是和</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">无关的，通过调用</span><span style="font-family: 'Arial','sans-serif'">save</span><span style="font-family: 宋体">把</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">保存到指定的</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">。一个</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">可以同时属于不同的</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">。因此</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">中就包含了一个</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">的指针集合。另外每个</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">里也要包括指向这条</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">的指针。</span></li>
    <li><span style="font-family: 'Arial','sans-serif'">copy Message</span><span style="font-family: 宋体">：包括拷贝</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">的文本内容以及一系列的</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">指针。同时对于每个</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">也要追加一个指向拷贝后的</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">的指针。</span></li>
    <li><span style="font-family: 宋体">赋值操作（</span><span style="font-family: 'Arial','sans-serif'">assignment</span><span style="font-family: 宋体">）：这个最搞</span><span style="font-family: 'Arial','sans-serif'">:D</span><span style="font-family: 宋体">。先要把等号左边的</span><span style="font-family: 'Arial','sans-serif'">message</span><span style="font-family: 宋体">对象从</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">中删除，再删除对象；然后把右边</span><span style="font-family: 'Arial','sans-serif'">message</span><span style="font-family: 宋体">对象的文本内容和</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">拷贝过来，同时还要向</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">指针追加指向左边</span><span style="font-family: 'Arial','sans-serif'">message</span><span style="font-family: 宋体">的指针。</span></li>
    <li><span style="font-family: 'Arial','sans-serif'">destroy</span><span style="font-family: 宋体">：除了要撤销这个</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">对象，同时也要删除掉各个</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">里面指向这个</span><span style="font-family: 'Arial','sans-serif'">Message</span><span style="font-family: 宋体">的指针。</span></li>
</ol>
<p><span style="font-family: 宋体">大师抽象出来两个操作：</span></p>
<ol style="margin-top: 0cm" type="1">
    <li><span style="font-family: 宋体">把</span><span style="font-family: 'Arial','sans-serif'">message</span><span style="font-family: 宋体">从</span><span style="font-family: 'Arial','sans-serif'">folder</span><span style="font-family: 宋体">中删除：</span></li>
</ol>
<p style="margin-left: 2cm; text-indent: -14.15pt"><span style="font-family: 'Arial','sans-serif'">void remove_Msg_from_Folders();</span></p>
<ol style="margin-top: 0cm" type="1" start="2">
    <li><span style="font-family: 宋体">把</span><span style="font-family: 'Arial','sans-serif'">message</span><span style="font-family: 宋体">追加到指定的</span><span style="font-family: 'Arial','sans-serif'">folider</span><span style="font-family: 宋体">：</span></li>
</ol>
<p style="margin-left: 42.55pt"><span style="font-family: 'Arial','sans-serif'">void put_Msg_in_Folders(const std::set&lt;Folder*&gt;&amp;);</span></p>
<h3><span style="font-family: 宋体">拷贝构造函数</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如果我们定义自己的拷贝构造函数，那么我们必须显式拷贝任何我们想要拷贝的成员，因为显式定义考别构造函数是不会自动拷贝任何东西的。（</span><span style="font-family: 'Arial','sans-serif'">When we write our own copy constructor, we must explicitly copy any members that we want copied. An explicitly defined copy constructor copies nothing automatically.</span><span style="font-family: 宋体">）就是说你要打算自己干就全部自己干，别指望编译器会为你拾遗补缺。</span></p>
<h2>13.5 Managing Pointer Members</h2>
<h3>Smart Point</h3>
<p><span style="font-family: 宋体">大师给出的办法就是对指针进行封装，定义一个新类，它包含有指针，以及使用的次数。下面这个类的定义高！实在是高！<strong><span style="color: fuchsia">就是这个友元的定义。</span></strong></span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: 'Arial','sans-serif'">// private class for use by HasPtr only</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;class U_Ptr {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; friend class HasPtr;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int *ip;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t use;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; U_Ptr(int *p): ip(p), use(1) { }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ~U_Ptr() { delete ip; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h3><span style="font-family: 宋体">拷贝控制成员</span>copy-control members</h3>
<p><span style="font-family: 宋体">包含指针成员的对象经常需要定义拷贝</span><span style="font-family: 'Arial','sans-serif'">-</span><span style="font-family: 宋体">控制成员。（</span><span style="font-family: 'Arial','sans-serif'">Objects with pointer members often need to define the copy-control members.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">拷贝</span><span style="font-family: 'Arial','sans-serif'">-</span><span style="font-family: 宋体">控制成员包括</span><span style="font-family: 'Arial','sans-serif'">:</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">赋值操作（</span><span style="font-family: 'Arial','sans-serif'">assignment operator</span><span style="font-family: 宋体">）</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">析构函数</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">拷贝构造函数（</span><span style="font-family: 'Arial','sans-serif'">copy constructor</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 'Arial','sans-serif'">smart pointer</span><span style="font-family: 宋体">类，使用计数器来管理它</span><span style="font-family: 'Arial','sans-serif'">smart pointer</span><span style="font-family: 宋体">类。拷贝</span><span style="font-family: 'Arial','sans-serif'">-</span><span style="font-family: 宋体">控制成员都会影响计数器的值。</span></p>
<h3><span style="font-family: 宋体">复习澄清一下：</span></h3>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 'Arial','sans-serif'">&#8216;.&#8217;</span><span style="font-family: 宋体">点操作符，</span><span style="font-family: 'Arial','sans-serif'">&#8217;*&#8217;</span><span style="font-family: 宋体">解引用操作符的优先级</span></p>
<p style="margin-left: 27pt"><span style="font-family: 'Arial','sans-serif'">&#8216;.&#8217;</span><span style="font-family: 宋体">点操作符的优先级高于解引用，所以要这样子写：</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p style="margin-left: 3.55pt"><span style="font-family: 'Arial','sans-serif'">Sales_item *sp = &amp;item1;</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: 'Arial','sans-serif'">(*sp).same_isbn(item2); // run same_isbn on object to which sp points</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 'Arial','sans-serif'">valuelike classes</span><span style="font-family: 宋体">和</span><span style="font-family: 'Arial','sans-serif'">pointlike classes</span><span style="font-family: 宋体">有什么区别？</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">这仅仅是一种很说法而已，</span><span style="font-family: 'Arial','sans-serif'">valuelike classes</span><span style="font-family: 宋体">，它的值</span><span style="font-family: 'Arial','sans-serif'">copy</span><span style="font-family: 宋体">后实际上是对应两个对象；而</span><span style="font-family: 'Arial','sans-serif'">pointlike classes</span><span style="font-family: 宋体">，</span><span style="font-family: 'Arial','sans-serif'">copy</span><span style="font-family: 宋体">的是指针，因此</span><span style="font-family: 'Arial','sans-serif'">copy</span><span style="font-family: 宋体">后实际上是指向的同一个对象。</span></p>
<img src ="http://www.blogjava.net/amenglai/aggbug/283855.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> 2009-06-24 08:17 <a href="http://www.blogjava.net/amenglai/articles/283855.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十二章 </title><link>http://www.blogjava.net/amenglai/articles/282513.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Tue, 16 Jun 2009 01:17:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/282513.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/282513.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/282513.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/282513.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/282513.html</trackback:ping><description><![CDATA[&nbsp;
<p style="text-align: center" align="center"><span style="font-size: 15pt">Classes</span></p>
<h2>12.1. <span style="font-family: 宋体">类的定义和声明</span> Class Definitions and Declarations</h2>
<h3><span style="font-family: 宋体">类定义</span></h3>
<p><span style="font-family: 宋体">大师仅仅写了这么一个类定义的简单的例子，却有这么多的东西可以说说啊</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">class Sales_item {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; // operations on Sales_item objects</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; double avg_price() const;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; bool same_isbn(const Sales_item &amp;rhs) const</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { return isbn == rhs.isbn; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; // default constructor needed to initialize members of built-in type</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; Sales_item(): units_sold(0), revenue(0.0) { }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; std::string isbn;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; unsigned units_sold;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; double revenue;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">};</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">double Sales_item::avg_price() const</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">{</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; if (units_sold)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return revenue/units_sold;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; else</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21.3pt; text-indent: -14.2pt"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 'Arial','sans-serif'">Member: data, functions or type definitions.</span></p>
<p style="margin-left: 21.3pt; text-indent: -14.2pt"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">构造函数</span><span style="font-family: 'Arial','sans-serif'">Constructors</span><span style="font-family: 宋体">初始化：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// default constructor needed to initialize members of built-in type</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">Sales_item(): units_sold(0), revenue(0.0) { }</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21.3pt"><span style="font-family: 宋体">这种写法是初始化内置数据类型。</span></p>
<p style="margin-left: 7.1pt; text-indent: 0cm"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 'Arial','sans-serif'">const:</span><span style="font-family: 宋体">表示</span><span style="font-family: 'Arial','sans-serif'">functions</span><span style="font-family: 宋体">不会修改数据成员。这可以用在查询或者判断类型的</span><span style="font-family: 'Arial','sans-serif'">functions</span><span style="font-family: 宋体">上。</span></p>
<p style="margin-left: 21.3pt; text-indent: -14.2pt"><span style="font-family: Symbol">&#183;<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">成员函数</span><span style="font-family: 'Arial','sans-serif'">member functions</span><span style="font-family: 宋体">必须在类的内部声明，成员函数的定义是否放在类定义里面是可选的。如果放在类里面，那么</span></p>
<h3><span style="font-family: 宋体">数据抽象和封装</span>Data Abstraction and Encapsulation</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类背后蕴涵的基本思想是数据抽象和封装。（</span><span style="font-family: 'Arial','sans-serif'">The fundamental ideas behind classes are data abstraction and encapsulation.</span><span style="font-family: 宋体">）数据抽象这种技术依赖于接口和实现的分离。（</span><span style="font-family: 'Arial','sans-serif'">Data abstraction is a programming (and design) technique that relies on the separation of interface and implementation.</span><span style="font-family: 宋体">）</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">多么精炼的话，包含了面向对象的深刻含义。大师啊。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类的用户（</span><span style="font-family: 'Arial','sans-serif'">user of class</span><span style="font-family: 宋体">）是谁？程序员</span><span style="font-family: 'Arial','sans-serif'">programmer</span><span style="font-family: 宋体">。</span><span style="font-family: 'Arial','sans-serif'">user of class</span><span style="font-family: 宋体">就如同</span><span style="font-family: 'Arial','sans-serif'">user of application</span><span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类的用户最关心啥？最关心的是接口。</span></p>
<h3>关于类定义的更多内容 more on class definitions</h3>
<h4><span style="font-family: 宋体">使用</span>Typedef<span style="font-family: 宋体">简化类</span></h4>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">class Screen {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; // interface member functions</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; typedef std::string::size_type index;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; std::string contents;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; index cursor;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; index height, width;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">注意：</span></p>
<p><span style="font-family: 'Arial','sans-serif'">typedef</span><span style="font-family: 宋体">是放在</span><span style="font-family: 'Arial','sans-serif'">public</span><span style="font-family: 宋体">部分的，这样</span><span style="font-family: 'Arial','sans-serif'">Screen</span><span style="font-family: 宋体">的用户都能够使用这个</span><span style="font-family: 'Arial','sans-serif'">typedef</span><span style="font-family: 宋体">。</span></p>
<h4><span style="font-family: 宋体">成员函数可被重载</span>Member Functions May Be Overloaded</h4>
<h4><span style="font-family: 宋体">显式指定</span> inline <span style="font-family: 宋体">成员函数</span>Explicitly Specifying inline Member Functions</h4>
<p><span style="font-family: 宋体">成员函数定义为</span><span style="font-family: 'Arial','sans-serif'">inline</span><span style="font-family: 宋体">。这个定义即可以在函数声明里，也可以在类定义之外。在类声明和类定义里把函数指定为</span><span style="font-family: 'Arial','sans-serif'">inline</span><span style="font-family: 宋体">都是合法的。（</span><span style="font-family: 'Arial','sans-serif'">It is legal to specify inline both on the declaration and definition.</span><span style="font-family: 宋体">）</span></p>
<h4><span style="font-family: 宋体">类声明与类定义</span></h4>
<p><span style="font-family: 宋体">类定义一般要放在头文件中。</span></p>
<p><span style="font-family: 宋体">类声明后，即使没有类定义，也可以作为引用或者指针来使用：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">class LinkScreen {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Screen window;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LinkScreen *next;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LinkScreen *prev;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 'Arial','sans-serif'">LinkScreen</span><span style="font-family: 宋体">定义完成之前，我们就定义了指向</span><span style="font-family: 'Arial','sans-serif'">LinkScreen</span><span style="font-family: 宋体">类型的指针。</span></p>
<p><span style="font-family: 宋体">这里引入了两个基本感念：</span></p>
<p><strong><span style="font-family: 宋体">前向声明</span></strong><strong><span style="font-family: 'Arial','sans-serif'">forward declaretion</span></strong><span style="font-family: 宋体">：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">class Screen; //definition of the Screen class</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">这就是一个前向声明。表示</span><span style="font-family: 'Arial','sans-serif'">Screen</span><span style="font-family: 宋体">是一个类类型（</span><span style="font-family: 'Arial','sans-serif'">class type</span><span style="font-family: 宋体">）。</span></p>
<p><strong><span style="font-family: 宋体">不完全类型</span></strong><strong><span style="font-family: 'Arial','sans-serif'">incompete type</span></strong><span style="font-family: 宋体">：在前向声明之后，类定义之前</span><span style="font-family: 'Arial','sans-serif'">Screen</span><span style="font-family: 宋体">就是一个不完全类型。意思是说知道</span><span style="font-family: 'Arial','sans-serif'">Screen</span><span style="font-family: 宋体">是个类型，但是不知道这个类型包括那些成员（</span><span style="font-family: 'Arial','sans-serif'">members</span><span style="font-family: 宋体">）。不完全类型只能用在有限的几种方式，它可以用来定义这种类型的指针或者是引用，也可以用在把这种类类型作为形参或者返回值类型的函数声明。（</span><span style="font-family: 'Arial','sans-serif'">An incomplete type may be used to define only pointers or references to the type or to declare (but not define) functions that use the type as a paremeter or return type.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">在创建某个类类型的对象前，这个类类型必须完整定义。这样编译器餐能够知道要为这种类型的对象保留多大的存储空间。</span></p>
<h2>12.2 隐含的this指针 The Implicit this Pointer</h2>
<h4><span style="font-family: 宋体">何时使用</span>this<span style="font-family: 宋体">？</span></h4>
<p style="text-indent: 21pt"><span style="font-family: 宋体">简单的说，就是当我们需要引用整个对象而不是对象中的成员的时候。最常见的情况是在返回值是被调用的对象的引用的函数里。（</span><span style="font-family: 'Arial','sans-serif'">when we need to refer to the object as a whole rather than to a member of the object. The most common case where we must use this is in functions that return a reference to the object on which they were invoked.</span><span style="font-family: 宋体">）</span></p>
<p style="text-indent: 21pt"><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">是指针，因此如果返回值是当前对象的引用，那么返回语句一定是：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">return *this;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">刚开始看到这个的时候，总是和</span><span style="font-family: 'Arial','sans-serif'">Java</span><span style="font-family: 宋体">搞混，因为</span><span style="font-family: 'Arial','sans-serif'">Java</span><span style="font-family: 宋体">是没有指针，所以返回的只能是</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">，显式使用的时候也是</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">。</span></p>
<h4><span style="font-family: 宋体">从</span>const<span style="font-family: 宋体">成员函数里返回</span>*this</h4>
<p><span style="font-family: 宋体">这里有两个规则：</span></p>
<ol style="margin-top: 0cm" type="1">
    <li><span style="font-family: 宋体">对于一般的非</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">成员函数，</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">的类型是一个</span><strong><span style="font-family: 'Arial','sans-serif'">const pointer</span></strong><span style="font-family: 宋体">。这意味我们可以修改</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">指向的对象的值，但是不能修改</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">保存的地址。（</span><span style="font-family: 'Arial','sans-serif'">In an ordinary nonconst member function, the type of this is a const pointer to the class type. We may change the value to which this points but cannot change the address that this holds.</span><span style="font-family: 宋体">）</span></li>
    <li><span style="font-family: 宋体">对于</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">成员函数，</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">的类型是<strong>一个指向</strong></span><strong><span style="font-family: 'Arial','sans-serif'">const </span></strong><strong><span style="font-family: 宋体">对象的</span></strong><strong><span style="font-family: 'Arial','sans-serif'">const pointer</span></strong><span style="font-family: 宋体">。这意味我们既不可以修改</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">指向的对象的值，也不能修改</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">保存的地址。（</span><span style="font-family: 'Arial','sans-serif'">In a const member function, the type of this is a const pointer to a const class-type object. We may change neither the object to which this points nor the address that this holds.</span><span style="font-family: 宋体">）</span></li>
</ol>
<h4><span style="font-family: 宋体">基于</span>const<span style="font-family: 宋体">的重载</span></h4>
<p><span style="font-family: 宋体">可以定义两个操作，一个是</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">，另一个不是，这也算是重载。</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">class Screen {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // interface member functions</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // display overloaded on whether the object is const or not</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; Screen&amp; display(std::ostream &amp;os)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { do_display(os); return *this; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; const Screen&amp; display(std::ostream &amp;os) const</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { do_display(os); return *this; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // single function to do the work of displaying a Screen,</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // will be called by the display operations</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void do_display(std::ostream &amp;os) const</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { os &lt;&lt; contents; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // as before</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">这样</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">对象使用</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">成员函数；非</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">对象可以使用任一成员函数，不过最好还是使用非</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">的成员函数。</span></p>
<p><span style="font-family: 宋体">对比下面的例子（基于指针形参是否指向</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">的函数重载）：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">Record lookup(Account&amp;);</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">Record lookup(const Account&amp;); // new function</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h4><span style="font-family: 宋体">可变数据成员</span>Mutable Data Members</h4>
<p><span style="font-family: 宋体">即使对象是</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">，有时我们也希望其中的某些数据成员是可以修改的，这就引出了</span><span style="font-family: 'Arial','sans-serif'">mutable</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">可变数据成员绝不是</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">，即使对象是</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">。这样</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">的成员函数也是可以修改可变数据成员的。</span></p>
<p><span style="font-family: 宋体">定义：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">class Screen {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;// interface member functions</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; mutable size_t access_ctr; // may change in a const members</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // other data members as before</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h2>12.3 类的作用范围</h2>
<h2>12.4构造函数Constructors</h2>
<p><span style="font-family: 宋体">构造函数不能声明为</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">建议的方法：使用构造函数初始化式</span><span style="font-family: 'Arial','sans-serif'">Constructor Initializer</span><span style="font-family: 宋体">。</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// recommended way to write constructors using a constructor initializer</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">Sales_item::Sales_item(const string &amp;book):</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; isbn(book), units_sold(0), revenue(0.0) { }</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h4>Constructor Initializer</h4>
<p><span style="font-family: 宋体">以下是正确的写法：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// recommended way to write constructors using a constructor initializer</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">Sales_item::Sales_item(const string &amp;book):</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; isbn(book), units_sold(0), revenue(0.0) { }</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">但是这种写法乍一看似乎和下面不使用</span><span style="font-family: 'Arial','sans-serif'">Constructor Initializer</span><span style="font-family: 宋体">的效果一样：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// legal but sloppier way to write the constructor:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// no constructor initializer</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">Sales_item::Sales_item(const string &amp;book)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">{</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; isbn = book;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; units_sold = 0;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; revenue = 0.0;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 'Arial','sans-serif'">NO</span><span style="font-family: 宋体">，</span><span style="font-family: 'Arial','sans-serif'">NO</span><span style="font-family: 宋体">，不一样。后一种写法那就像郭德纲相声说的房都烧没了，就剩下个防盗门，于谦还开门进去。</span><span style="font-family: 'Arial','sans-serif'">isbn</span><span style="font-family: 宋体">的初始化是在构造函数执行之前完成的。上面这个写法先用缺省的</span><span style="font-family: 'Arial','sans-serif'">string</span><span style="font-family: 宋体">的构造函数初始化</span><span style="font-family: 'Arial','sans-serif'">isbn</span><span style="font-family: 宋体">，在构造函数的函数体执行时，</span><span style="font-family: 'Arial','sans-serif'">isbn</span><span style="font-family: 宋体">又重新赋值为</span><span style="font-family: 'Arial','sans-serif'">book</span><span style="font-family: 宋体">。没效率啊！但是对于内置类型来说，两种方式无论是在结果上还是在性能上又都是没有区别的。</span></p>
<p><span style="font-family: 宋体">构造函数的执行分成两个步骤：</span></p>
<ol style="margin-top: 0cm" type="1">
    <li><span style="font-family: 宋体">初始化阶段，类的数据成员是在这个阶段初始化的。</span></li>
    <li><span style="font-family: 宋体">一般计算阶段，这就是指构造函数函数体的执行。</span></li>
</ol>
<p><span style="font-family: 宋体">在计算阶段前初始化阶段就开始了。（</span><span style="font-family: 'Arial','sans-serif'">Initialization happens before the computation phase begins.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">在一些特定的情况下必须使用</span><span style="font-family: 'Arial','sans-serif'">Constructor Initializer</span><span style="font-family: 宋体">，这些特殊的情况包括：</span></p>
<ol style="margin-top: 0cm" type="1">
    <li><span style="font-family: 宋体">数据成员没有缺省的构造函数</span></li>
    <li><span style="font-family: 宋体">数据成员是</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">或者是引用</span></li>
</ol>
<p><span style="font-family: 'Arial','sans-serif'">for example: </span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// legal but sloppier way to write the constructor:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// no constructor initializer</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">class ConstRef {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; ConstRef(int ii);</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; int i;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; const int ci;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; int &amp;ri;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;// no explicit constructor initializer: error ri is uninitialized</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;ConstRef::ConstRef(int ii)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // assignments:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = ii;&nbsp;&nbsp; // ok</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ci = ii;&nbsp;// error: cannot assign to a const</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ri = i;&nbsp;&nbsp; // assigns to ri which was not bound to an object</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">正确写法：只有用</span><span style="font-family: 'Arial','sans-serif'">constructor initializer</span><span style="font-family: 宋体">才有机会对</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">和引用进行初始化。</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">ConstRef::ConstRef(int ii): i(ii), ci(i), ri(ii) { }</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h4><span style="font-family: 宋体">成员初始化顺序</span></h4>
<p><span style="font-family: 宋体">成员的初始化顺序就是成员的定义的顺序。第一个定义的成员第一个初始化，然后是下一个，以此类推。（</span><span style="font-family: 'Arial','sans-serif'">The order in which members are initialized is the order in which the members are defined. The first member is initialized first, then the next, and so on.</span><span style="font-family: 宋体">）</span></p>
<h4><span style="font-family: 宋体">类类型的数据成员的初始化</span>Initializers for Data Members of Class Type</h4>
<p><span style="font-family: 'Arial','sans-serif'">Constructor Initializer</span><span style="font-family: 宋体">初始化式使用类的某一个构造函数来完成。</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// alternative definition for Sales_item default constructor</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">Sales_item(): isbn(10, '9'), units_sold(0), revenue(0.0) {}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">缺省构造函数</span></p>
<p><span style="font-family: 宋体">只有在类没有定义任何一个构造函数时，编译器才会自动生成缺省的构造函数。</span></p>
<h4><span style="font-family: 宋体">隐式类类型转换</span> Implicit Class-Type Conversions</h4>
<h2>12.5. 友元Friends</h2>
<p><span style="font-family: 宋体">友元就是允许其它特定的类和方法来访问它的非</span><span style="font-family: 'Arial','sans-serif'">public</span><span style="font-family: 宋体">的成员。（</span><span style="font-family: 'Arial','sans-serif'">The friend mechanism allows a class to grant access to its nonpublic members to specified functions or classes.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">友元定义：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">class Screen {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // Window_Mgr members can access private parts of class Screen</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; friend class Window_Mgr;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // ...rest of the Screen class</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">友元不是类的成员，但是他们是类的接口的组成部分。（</span><span style="font-family: 'Arial','sans-serif'">even if they are not members of the class, they are "part of the interface" to the class.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">友元可以是：</span></p>
<p style="margin-left: 36pt; text-indent: -18pt; tab-stops: list 36.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">类</span></p>
<p style="margin-left: 36pt; text-indent: -18pt; tab-stops: list 36.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">类的成员函数</span></p>
<table style="margin-left: 41.4pt; width: 324pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="432" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 324pt; padding-top: 0cm" valign="top" width="432">
            <p><span style="font-family: 'Arial','sans-serif'">class Screen {</span></p>
            <p style="text-indent: 10.5pt"><span style="font-family: 'Arial','sans-serif'">// Window_Mgr must be defined before class Screen</span></p>
            <p style="text-indent: 10.5pt"><span style="font-family: 'Arial','sans-serif'">friend Window_Mgr&amp;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; Window_Mgr::relocate(Screen::index r, Screen::index c,</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Screen&amp; s);</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // ...rest of the Screen class</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 36pt; text-indent: -18pt; tab-stops: list 36.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">一般的非成员函数</span></p>
<h3>友元声明和范围</h3>
<p><span style="font-family: 宋体">友元声明和友元定义之间存在的相互依赖关系使得我们小心地构造类。再看上面的例子</span><span style="font-family: 'Arial','sans-serif'">:</span></p>
<p><span style="font-family: 'Arial','sans-serif'">Window_Mgr</span><span style="font-family: 宋体">必须要的</span><span style="font-family: 'Arial','sans-serif'">Screen</span><span style="font-family: 宋体">前定义。但是成员方法</span><span style="font-family: 'Arial','sans-serif'">relocate</span><span style="font-family: 宋体">要在</span><span style="font-family: 'Arial','sans-serif'">Screen</span><span style="font-family: 宋体">定义后才能定义。靠，这就像是先有蛋还是先有鸡一样拧巴。</span></p>
<table style="margin-left: 41.4pt; width: 324pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="432" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 324pt; padding-top: 0cm" valign="top" width="432">
            <p><span style="font-family: 'Arial','sans-serif'">class Screen {</span></p>
            <p style="text-indent: 10.5pt"><span style="font-family: 'Arial','sans-serif'">// Window_Mgr must be defined before class Screen</span></p>
            <p style="text-indent: 10.5pt"><span style="font-family: 'Arial','sans-serif'">friend Window_Mgr&amp;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; Window_Mgr::relocate(Screen::index r, Screen::index c,</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Screen&amp; s);</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; // ...rest of the Screen class</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h2>12.6. static 类成员static Class Members</h2>
<p><span style="font-family: 宋体">这句话是对</span><span style="font-family: 'Arial','sans-serif'">static class member</span><span style="font-family: 宋体">的最重要的解释：</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">静态数据成员独立于类的任何对象而存在，每个静态数据成员是和类相关的对象，而不是和类的对象相关。（</span><span style="font-family: 'Arial','sans-serif'">a static data member exists independently of any object of its class; each static data member is an object associated with the class, not with the objects of that class.</span><span style="font-family: 宋体">）</span></p>
<h3>使用静态数据成员的好处</h3>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 'Arial','sans-serif'">static</span><span style="font-family: 宋体">成员的名字的作用范围是类，因此可以避免和其它的类的成员或者全局对象的名字的冲突。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">强制进行封装。</span><span style="font-family: 'Arial','sans-serif'">static</span><span style="font-family: 宋体">成员可以是</span><span style="font-family: 'Arial','sans-serif'">private</span><span style="font-family: 宋体">的，而全局对象是不可以的。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">如果把</span><span style="font-family: 'Arial','sans-serif'">static</span><span style="font-family: 宋体">成员关联到某个特殊的类上，这样易于阅读代码。</span></p>
<h3>静态成员函数static member function</h3>
<p><span style="font-family: 宋体">在静态成员函数（</span><span style="font-family: 'Arial','sans-serif'">static member function</span><span style="font-family: 宋体">）中是不能使用</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">指针的。这其实很好理解，因为</span><span style="font-family: 'Arial','sans-serif'">this</span><span style="font-family: 宋体">指针指向的是对象，而静态成员函数并不属于任何的对象。</span></p>
<h3>静态数据成员static data members</h3>
<p><span style="font-family: 宋体">静态数据成员可以是任何的类型：</span><span style="font-family: 'Arial','sans-serif'">const</span><span style="font-family: 宋体">，引用</span><span style="font-family: 'Arial','sans-serif'">reference</span><span style="font-family: 宋体">，数组，指针类。</span></p>
<table style="margin-left: 41.4pt; width: 324pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="432" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 324pt; padding-top: 0cm" valign="top" width="432">
            <p><span style="font-family: 'Arial','sans-serif'">class Account {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; // interface functions here</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; void applyint() { amount += amount * interestRate; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; static double rate() { return interestRate; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; static void rate(double); // sets a new rate</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; std::string owner;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; double amount;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; static double interestRate; //</span><span style="font-family: 宋体">这是声明</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; static double initRate();</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">};</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// define and initialize static class member</span><span style="font-family: 宋体">，这是定义</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">double Account::interestRate = initRate();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">以上是一个完整的</span><span style="font-family: 'Arial','sans-serif'">static</span><span style="font-family: 宋体">的定义，要注意以下几点：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: 'Arial','sans-serif'">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">静态数据成员要在类定义体之外来定义。（</span><span style="font-family: 'Arial','sans-serif'">static data members must be defined (exactly once) outside the class body.</span><span style="font-family: 宋体">）</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: 'Arial','sans-serif'">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">静态成员不能通过构造函数进行初始化，而是在定义的时候就完成了初始化。（</span><span style="font-family: 'Arial','sans-serif'">static members are not initialized through the class constructor(s) and instead should be initialized when they are defined.</span><span style="font-family: 宋体">）</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: 'Arial','sans-serif'">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">关键字</span><span style="font-family: 'Arial','sans-serif'">static</span><span style="font-family: 宋体">只是用在类体内的成员声明，而当在类的外面的对静态数据成员进行定义时，就不要再使用关键字</span><span style="font-family: 'Arial','sans-serif'">static</span><span style="font-family: 宋体">。（</span><span style="font-family: 'Arial','sans-serif'">The static keyword, however, is used only on the declaration inside the class body. Definitions are not labeled static.</span><span style="font-family: 宋体">）</span></p>
<h4><span style="font-family: 宋体">整型类型的静态数据成员可以在类定义体内直接定义，只要是初始化值是常量表达式。</span></h4>
<p><span style="font-family: 'Arial','sans-serif'">a const static data member of integral type can be initialized within the class body as long as the initializer is a constant expression</span></p>
<p><span style="font-family: 'Arial','sans-serif'">period</span><span style="font-family: 宋体">的定义就是这样：</span></p>
<table style="margin-left: 41.4pt; width: 324pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="432" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 324pt; padding-top: 0cm" valign="top" width="432">
            <p><span style="font-family: 'Arial','sans-serif'">class Account {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static double rate() { return interestRate; }</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void rate(double);&nbsp;// sets a new rate</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static const int period = 30; // interest posted every 30 days</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double daily_tbl[period]; // ok: period is constant expression</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// definition of static member with no initializer;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// the initial value is specified inside the class definition</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">const int Account::period;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">注意：虽然</span><span style="font-family: 'Arial','sans-serif'">period</span><span style="font-family: 宋体">在类定义体内完成了初始化，但是还是要在类定义之外定义数据成员。（</span><span style="font-family: 'Arial','sans-serif'">When a const static data member is initialized in the class body, the data member must still be defined outside the class definition.</span><span style="font-family: 宋体">）</span></p>
<h3>静态成员不是类对象的一部分</h3>
<p><span style="font-family: 宋体">也正因为如此，对于非静态成员的非法的使用方式，对于静态成员来说就是合法的。例如：静态成员的类型可以是它所属类的类型。非静态数据成员被严格限制只能是它所属类的对象的引用或者是指针。（</span><span style="font-family: 'Arial','sans-serif'">the type of a static data member can be the class type of which it is a member. A nonstatic data member is restricted to being declared as a pointer or a reference to an object of its class:</span><span style="font-family: 宋体">）</span></p>
<table style="margin-left: 41.4pt; width: 324pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="432" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 324pt; padding-top: 0cm" valign="top" width="432">
            <p><span style="font-family: 'Arial','sans-serif'">class Bar {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;public:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ...</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;private:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static Bar mem1; // ok</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bar *mem2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ok</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bar mem3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // error</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/amenglai/aggbug/282513.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> 2009-06-16 09:17 <a href="http://www.blogjava.net/amenglai/articles/282513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十一章</title><link>http://www.blogjava.net/amenglai/articles/279983.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Thu, 04 Jun 2009 03:22:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/279983.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/279983.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/279983.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/279983.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/279983.html</trackback:ping><description><![CDATA[<p>&nbsp; </p>
<p style="text-align: center" align="center"><span style="font-size: 15pt; font-family: 宋体">泛型算法</span></p>
<p><span style="font-family: 宋体">算法为了保持独立性，不使用容器类型，而使用<strong>迭代器</strong>。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">算法绝不执行容器操作。算法仅仅是根据迭代器和迭代器操作来操作的。因此所有会改变迭代器的操作在通用算法里都不会出现。例如增加或删除元素。但是这些通用算法有可能会修改容器中元素的值，也可能会在容器中移动元素。</span></p>
<h2>11.2 <span style="font-family: 黑体">初窥算法</span></h2>
<p><span style="font-family: 宋体">必须要包含一下的头文件：</span></p>
<p style="margin-left: 17.95pt"><em><span style="font-family: 'Arial','sans-serif'">#include &lt;algorithm&gt;</span></em></p>
<p style="margin-left: 17.95pt"><em><span style="font-family: 'Arial','sans-serif'">#include &lt;numeric&gt;</span></em></p>
<h3><span style="font-family: 宋体">只读算法</span></h3>
<h4>accumulate</h4>
<p><span style="font-family: 宋体">这个算法的参数很好说明了算法实际上是不知道元素的类型的。第三个参数指定了起始值，因为</span><span style="font-family: 'Arial','sans-serif'">accumnulate</span><span style="font-family: 宋体">不知道它正在汇总的元素的类型。</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">int sum = accumulate(vec.begin(), vec.end(), 42);</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><span style="font-family: 宋体">另一个例子：</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">string sum = accumulate(v.begin(), v.end(), string(""));</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><span style="font-family: 宋体">这里一定要指定起始值是</span><span style="font-family: 'Arial','sans-serif'">string</span><span style="font-family: 宋体">，而绝不能写成字符串常量，因为字符串常量对应的数据类型是</span><span style="font-family: 'Arial','sans-serif'">const char*</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">有趣！</span></p>
<h4>find_first_of</h4>
<p><span style="font-family: 宋体">需要两对迭代器：</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">size_t cnt = 0;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">list&lt;string&gt;::iterator it = roster1.begin();</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// look in roster1 for any name also in roster2</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">while&nbsp;&nbsp; ((it = find_first_of(it, roster1.end(),</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; roster2.begin(), roster2.end()))</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; != roster1.end()) {</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; ++cnt;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; // we got a match, increment it to look in the rest of roster1</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; ++it;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><span style="font-family: 'Arial','sans-serif'">roster1</span><span style="font-family: 宋体">是</span><span style="font-family: 'Arial','sans-serif'">list</span><span style="font-family: 宋体">，</span><span style="font-family: 'Arial','sans-serif'">roster2</span><span style="font-family: 宋体">可以是</span><span style="font-family: 'Arial','sans-serif'">deque</span><span style="font-family: 宋体">，</span><span style="font-family: 'Arial','sans-serif'">vector</span><span style="font-family: 宋体">，只要我们可以用</span><span style="font-family: 'Arial','sans-serif'">==</span><span style="font-family: 宋体">操作比较这两个序列中的元素。尤其是：如果</span><span style="font-family: 'Arial','sans-serif'"> roster1 </span><span style="font-family: 宋体">是</span><span style="font-family: 'Arial','sans-serif'"> list&lt;string&gt; </span><span style="font-family: 宋体">对象，则</span><span style="font-family: 'Arial','sans-serif'"> roster2 </span><span style="font-family: 宋体">可以是</span><span style="font-family: 'Arial','sans-serif'"> vector&lt;char*&gt; </span><span style="font-family: 宋体">对象，因为</span><span style="font-family: 'Arial','sans-serif'"> string </span><span style="font-family: 宋体">标准库为</span><span style="font-family: 'Arial','sans-serif'"> string </span><span style="font-family: 宋体">对象与</span><span style="font-family: 'Arial','sans-serif'"> char* </span><span style="font-family: 宋体">对象定义了相等（</span><span style="font-family: 'Arial','sans-serif'">==</span><span style="font-family: 宋体">）操作符。</span></p>
<h4>总结一下迭代器实参类型</h4>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">标记范围的两个实参类型必须精确匹配，必须指向同一个容器中的元素（或者超出容器末端的下一位置），并且如果两者不相等，则第一个迭代器通过不断地自增，必须可以到达第二个迭代器。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 宋体">带有两对迭代器参数。每对迭代器中，两个实参的类型必须精确匹配，但不要求两对之间的类型匹配。特别是，元素可存储在不同类型序列中，只要这两序列的元素可以比较即可。</span></p>
<h3><span style="font-family: 宋体">写容器算法</span></h3>
<p><span style="font-family: 宋体">写容器算法最重要的一点是必须保证算法所写的序列至少要和被写入的元素数目一样大。（</span><span style="font-family: 'Arial','sans-serif'">we must take care to ensure that the sequence into which the algorithm writes is at least as large as the number of elements being written.</span><span style="font-family: 宋体">）就是说如果指定的要写入的序列范围必须是有效的，必须大于要写入的元素数目，就是说不能越界。</span></p>
<p><span style="font-family: 宋体">看个最一目了然的例子就是：</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">vector&lt;int&gt; vec; // empty vector</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// disaster: attempts to write to 10 (nonexistent) elements in vec</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">fill_n(vec.begin(), 10, 0);</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><span style="font-family: 'Arial','sans-serif'">back_inserter</span></p>
<p><span style="font-family: 宋体">使用</span><span style="font-family: 'Arial','sans-serif'">back_inserter</span><span style="font-family: 宋体">之所以安全，是因为如果指定的范围越界，它执行的并不是数据修改操作而是数据添加操作。</span></p>
<h3><span style="font-family: 宋体">容器元素重新排序算法</span></h3>
<p><span style="font-family: 'Arial','sans-serif'">unique</span></p>
<p><span style="font-family: 'Arial','sans-serif'">sort</span></p>
<p><span style="font-family: 'Arial','sans-serif'">stable_sort</span></p>
<p><span style="font-family: 宋体">谓词</span><span style="font-family: 'Arial','sans-serif'">predicates</span></p>
<h2><span style="font-family: 黑体">再次解读迭代器</span>Iterators</h2>
<p><span style="font-family: 宋体">三类迭代器：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 'Arial','sans-serif'">insert iterators</span><span style="font-family: 宋体">插入迭代器</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 'Arial','sans-serif'">iostream iterators</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l&nbsp;</span><span style="font-family: 'Arial','sans-serif'">reverse iterators</span><span style="font-family: 宋体">反向迭代器</span></p>
<h3><span style="font-family: 'Arial','sans-serif'">insert iterators</span></h3>
<p><span style="font-family: 'Arial','sans-serif'">inserter</span><span style="font-family: 宋体">是迭代器适配器，它和容器绑定，产生一个迭代器，这个迭代器向绑定的容器插入元素。当我们通过</span><span style="font-family: 'Arial','sans-serif'">inserter</span><span style="font-family: 宋体">迭代器赋值时，迭代器插入新的元素。（</span><span style="font-family: 'Arial','sans-serif'">An inserter is an iterator adaptor that takes a container and yields an iterator that inserts elements into the specified container. When we assign through an insert iterator, the iterator inserts a new element.</span><span style="font-family: 宋体">）</span></p>
<p><span style="font-family: 宋体">又分成</span><span style="font-family: 'Arial','sans-serif'">3</span><span style="font-family: 宋体">类：</span></p>
<ul style="margin-top: 0cm" type="disc">
    <li><span style="font-family: 'Arial','sans-serif'">back_inserter</span><span style="font-family: 宋体">：使用</span><span style="font-family: 'Arial','sans-serif'">push_back</span><span style="font-family: 宋体">创建一个迭代器</span></li>
    <li><span style="font-family: 'Arial','sans-serif'">front_inserter: </span><span style="font-family: 宋体">使用</span><span style="font-family: 'Arial','sans-serif'">push_front</span><span style="font-family: 宋体">创建一个迭代器</span></li>
    <li><span style="font-family: 'Arial','sans-serif'">inserter</span><span style="font-family: 宋体">：在指定的位置后创建迭代器</span></li>
</ul>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">list&lt;int&gt; ilst, ilst2, ilst3;&nbsp;&nbsp;&nbsp;&nbsp; // empty lists</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// after this loop ilst contains: 3 2 1 0</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">for (list&lt;int&gt;::size_type i = 0; i != 4; ++i)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp;&nbsp; ilst.push_front(i);</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// after copy ilst2 contains: 0 1 2 3</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">copy (ilst.begin(), ilst.end(), front_inserter(ilst2));</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// after copy, ilst3 contains: 3 2 1 0</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">copy (ilst.begin(), ilst.end(), inserter (ilst3, ilst3.begin()));</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<h3><span style="font-family: 'Arial','sans-serif'">iostream iterators</span></h3>
<p><span style="font-family: 'Arial','sans-serif'">istream_iterator:</span><span style="font-family: 宋体">读</span><span style="font-family: 'Arial','sans-serif'">input stream</span></p>
<p><span style="font-family: 'Arial','sans-serif'">ostream_iterator:</span><span style="font-family: 宋体">写</span><span style="font-family: 'Arial','sans-serif'">output stream</span></p>
<h4><span style="font-family: 宋体">定义流迭代器</span>stream Iterators</h4>
<p><span style="font-family: 宋体">流迭代器都是模板</span><span style="font-family: 'Arial','sans-serif'">Templates</span><span style="font-family: 宋体">。</span><span style="font-family: 'Arial','sans-serif'">Example: </span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">istream_iterator&lt;int&gt; cin_it(cin);&nbsp;&nbsp;&nbsp; // reads ints1 from cin</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">istream_iterator&lt;int&gt; end_of_stream;&nbsp;// end iterator value</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">while(cin_it != end_of_stream)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">{</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; //do something</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">}</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// writes Sales_items from the ofstream named outfile</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// each element is followed by a space</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">ofstream outfile;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">ostream_iterator&lt;Sales_item&gt; output(outfile, " ");</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<h4>istream_iterator上的操作</h4>
<p><em><span style="font-family: 'Arial','sans-serif'">++it &amp; it++</span></em></p>
<p><span style="font-family: 宋体">迭代器加</span><span style="font-family: 'Arial','sans-serif'">1</span><span style="font-family: 宋体">，一般前缀加</span><span style="font-family: 'Arial','sans-serif'">1</span><span style="font-family: 宋体">，返回的是增加后的迭代器的引用。后缀加</span><span style="font-family: 'Arial','sans-serif'">1</span><span style="font-family: 宋体">，迭代器也加</span><span style="font-family: 'Arial','sans-serif'">1</span><span style="font-family: 宋体">，但是返回的是未加</span><span style="font-family: 'Arial','sans-serif'">1</span><span style="font-family: 宋体">的那个值。</span></p>
<p><span style="font-family: 宋体">大师给出了一个</span><span style="font-family: 'Arial','sans-serif'">istream_iterator</span><span style="font-family: 宋体">和</span><span style="font-family: 'Arial','sans-serif'">ostream_iterator</span><span style="font-family: 宋体">这两种迭代器的最经典的应用，输入转输出，有这个</span><span style="font-family: 'Arial','sans-serif'">sample</span><span style="font-family: 宋体">这是很容易理解这两个东西：</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// write one string per line to the standard output</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">ostream_iterator&lt;string&gt; out_iter(cout, ""n");</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// read strings from standard input and the end iterator</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">istream_iterator&lt;string&gt; in_iter(cin), eof;</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// read until eof and write what was read to the standard output</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">while (in_iter != eof)</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; // write value of in_iter to standard output</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp;&nbsp; // and then increment the iterator to get the next value from cin</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">&nbsp;&nbsp; *out_iter++ = *in_iter++;</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<h4>流迭代器的限制</h4>
<p style="margin-left: 1cm; text-indent: -21.25pt"><span style="font-family: 'Arial','sans-serif'">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">不能从</span><span style="font-family: 'Arial','sans-serif'">ostream_iterator</span><span style="font-family: 宋体">中读入数据，同时也不能向</span><span style="font-family: 'Arial','sans-serif'">istream_iterator</span><span style="font-family: 宋体">写入数据（</span><span style="font-family: 'Arial','sans-serif'">It is not possible to read from an ostream_iterator, and it is not possible to write to an istream_iterator.</span><span style="font-family: 宋体">）</span></p>
<p style="margin-left: 1cm; text-indent: -21.25pt"><span style="font-family: 'Arial','sans-serif'">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">一旦给</span><span style="font-family: 'Arial','sans-serif'">ostream_iterator</span><span style="font-family: 宋体">赋值，这个写入的操作就提交了。一旦赋值，在后续的操作中就不能修改。此外，每个</span><span style="font-family: 'Arial','sans-serif'">ostream_iterator</span><span style="font-family: 宋体">只能用作输出一次。（</span><span style="font-family: 'Arial','sans-serif'">Once we assign a value to an ostream_iterator, the write is committed. There is no way to subsequently change a value once it is assigned. Moreover, each distinct value of an ostream_iterator is expected to be used for output exactly once.</span><span style="font-family: 宋体">）</span></p>
<p style="margin-left: 1cm; text-indent: -21.25pt"><span style="font-family: 'Arial','sans-serif'">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">在</span><span style="font-family: 'Arial','sans-serif'">ostream_iterator</span><span style="font-family: 宋体">里没有</span><span style="font-family: 'Arial','sans-serif'">-&gt;</span><span style="font-family: 宋体">操作。</span></p>
<h4>基于流迭代器使用算法</h4>
<p><span style="font-family: 宋体">既然流迭代器基本上可以看做一般意义上的迭代器，那么前面所描述的算法应该同时也适用在流迭代器上。于是，针对流迭代器，我们也可以进行排序，比较等算法操作。</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">istream_iterator&lt;int&gt; cin_it(cin);&nbsp;&nbsp;&nbsp; // reads ints from cin</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">istream_iterator&lt;int&gt; end_of_stream;&nbsp;// end iterator value</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// initialize vec from the standard input:</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">vector&lt;int&gt; vec(cin_it, end_of_stream);</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">sort(vec.begin(), vec.end());</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// writes ints to cout using " " as the delimiter</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">ostream_iterator&lt;int&gt; output(cout, " ");</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// write only the unique elements in vec to the standard output</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">unique_copy(vec.begin(), vec.end(), output);</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<h3><span style="font-family: 'Arial','sans-serif'">reverse iterators</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">从这张图上可以看出普通迭代器和反向迭代器的区别，另外二者都能够执行自增和自减操作，形式是一样的，但本质是不同的。例如形式上都是自增，迭代器都会由</span><span style="font-family: 'Arial','sans-serif'">begin</span><span style="font-family: 宋体">向</span><span style="font-family: 'Arial','sans-serif'">end</span><span style="font-family: 宋体">方向移动，但是二者却是反方向的。这样做的最大好处是：我们能够透明地使用算法向前或者向后处理容器。</span></p>
<h4><span style="font-family: 宋体">利用迭代器处理</span>string</h4>
<p><span style="font-family: 宋体">可以达到</span><span style="font-family: 'Arial','sans-serif'">java</span><span style="font-family: 宋体">中</span><span style="font-family: 'Arial','sans-serif'">StringToken</span><span style="font-family: 宋体">的功能：我喜欢这段代码</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// find first element in a comma-separated list</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">string::iterator comma = find(line.begin(), line.end(), ',');</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">cout &lt;&lt; string(line.begin(), comma) &lt;&lt; endl;</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p><span style="font-family: 宋体">反向迭代器获得最后一个单词：</span></p>
<p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: 'Arial','sans-serif'">// find last element in a comma-separated list</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">string::reverse_iterator rcomma = find(line.rbegin(), line.rend(), ',');</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">// wrong: will generate the word in reverse order</span></p>
            <p><span style="font-family: 'Arial','sans-serif'">cout &lt;&lt; string(rcomma.base(), line.end()) &lt;&lt; endl;</span></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">反向迭代器可以代表迭代器范围以及这个范围是不对称的事实产生一个重要的结论。当我们用一般的迭代器对反向迭代器初始化或者赋值时，所得到的迭代器所指向的元素和初始值不一样。（</span><span style="font-family: 'Arial','sans-serif'">The fact that reverse iterators are intended to represent ranges and that these ranges are asymmetric has an important consequence. When we initialize or assign a reverse iterator from a plain iterator, the resulting iterator does not refer to the same element as the original.</span><span style="font-family: 宋体">）</span></p>
<h2><span style="font-family: 黑体">泛型算法结构</span></h2>
<p><span style="font-family: 'Arial','sans-serif'">Nothing to say</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">其实就是对算法进行了分类，同时对于算法的命名习惯加以阐述，看完了，觉得跳过也无妨哈。</span></p>
<h2><span style="font-family: 黑体">容器特有算法</span></h2>
<p><span style="font-family: 宋体">就是针对</span><span style="font-family: 'Arial','sans-serif'">list</span><span style="font-family: 宋体">，为了性能优化，对于算法，</span><span style="font-family: 'Arial','sans-serif'">list</span><span style="font-family: 宋体">重新实现。</span></p>
 <img src ="http://www.blogjava.net/amenglai/aggbug/279983.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> 2009-06-04 11:22 <a href="http://www.blogjava.net/amenglai/articles/279983.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第十章</title><link>http://www.blogjava.net/amenglai/articles/279982.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Thu, 04 Jun 2009 03:22:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/279982.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/279982.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/279982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/279982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/279982.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;关联容器 Associative Containers&nbsp;关联容器包括：l&nbsp; mapl&nbsp; setl&nbsp; multimapl&nbsp; multiset&nbsp;10.1 初步知识：pair类型创建和初始化pairsExamples:                          ...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/279982.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/279982.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> 2009-06-04 11:22 <a href="http://www.blogjava.net/amenglai/articles/279982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第九章</title><link>http://www.blogjava.net/amenglai/articles/279981.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Thu, 04 Jun 2009 03:21:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/279981.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/279981.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/279981.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/279981.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/279981.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;顺序容器 Sequential Containers&nbsp;类库中定义了3种顺序容器：vector, list, deque。对应3种适配器：stack, queue, priority_queue。什么是适配器？每种适配器都会对应一种容器，根据原始数据类型的操作重新定义了接口。9.1 定义顺序容器容器初始化的方法有：1.&nbsp;&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/279981.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/279981.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> 2009-06-04 11:21 <a href="http://www.blogjava.net/amenglai/articles/279981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第八章</title><link>http://www.blogjava.net/amenglai/articles/277857.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Mon, 25 May 2009 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/277857.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/277857.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/277857.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/277857.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/277857.html</trackback:ping><description><![CDATA[&nbsp;
<p style="text-align: center" align="center"><span style="font-size: 15pt">The IO Library</span><span style="font-size: 15pt; font-family: 宋体">标准</span><span style="font-size: 15pt"> IO </span><span style="font-size: 15pt; font-family: 宋体">库</span></p>
<h2>8.1 An Object-Oriented Library</h2>
<p><span style="font-family: 宋体">标准</span><span style="font-family: Arial">IO</span><span style="font-family: 宋体">库实际上是针对三类流</span><span style="font-family: Arial">stream</span><span style="font-family: 宋体">的操作</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p style="text-align: center" align="center"><span style="font-family: Arial">stream</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; border-left: medium none; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p style="text-align: center" align="center"><span style="font-family: Arial">Header</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; border-left: medium none; width: 106.55pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p style="text-align: center" align="center"><span style="font-family: Arial">Type</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; border-left: medium none; width: 106.55pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142"></td>
        </tr>
        <tr style="page-break-inside: avoid">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">console</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">iostream</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 106.55pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">istream</span></p>
            <p><span style="font-family: Arial">ostream</span></p>
            <p><span style="font-family: Arial">iostream</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 106.55pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142" rowspan="3">
            <p><span style="font-family: 宋体">提供</span></p>
            <p><span style="font-family: Arial">char</span></p>
            <p><span style="font-family: Arial">wchar_t</span></p>
            <p><span style="font-family: Arial">cin</span></p>
            <p><span style="font-family: Arial">wcin</span></p>
            <p><span style="font-family: Arial">&#8230;</span></p>
            </td>
        </tr>
        <tr style="page-break-inside: avoid">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">string stream</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">sstream</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 106.55pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">istringstream</span></p>
            <p><span style="font-family: Arial">ostringstream</span></p>
            <p><span style="font-family: Arial">stringstream</span></p>
            </td>
        </tr>
        <tr style="page-break-inside: avoid">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">file</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 106.5pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">fstream</span></p>
            </td>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 106.55pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="142">
            <p><span style="font-family: Arial">ifstream</span></p>
            <p><span style="font-family: Arial">ofstream</span></p>
            <p><span style="font-family: Arial">fstream</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">对于</span><span style="font-family: Arial">IO</span><span style="font-family: 宋体">对象来说是不能拷贝或赋值的，因此这些写法都是会死人的：</span></p>
<table style="margin-left: 14.4pt; width: 387pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 387pt; padding-top: 0cm" valign="top" width="516">
            <p><span style="font-family: Arial">ofstream out1, out2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">out1 = out2;&nbsp;&nbsp; // error: cannot assign stream objects&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">ofstream print(ofstream);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">out2 = print(out2);&nbsp;// error: cannot copy stream objects</span><span style="font-family: 宋体">，形参不能是</span><span style="font-family: Arial">IO</span><span style="font-family: 宋体">类型</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">形参不能是</span><span style="font-family: Arial">IO</span><span style="font-family: 宋体">类型。返回值也不能是</span><span style="font-family: Arial">IO</span><span style="font-family: 宋体">类型。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">IO</span><span style="font-family: 宋体">对象也不能保存在</span><span style="font-family: Arial">vector</span><span style="font-family: 宋体">这样的集合容器里。</span></p>
<h2>8.2 <span style="font-family: 黑体">条件状态</span>Condition States</h2>
<p><span style="font-family: 宋体">条件状态成员是做什么用的？</span></p>
<p style="text-indent: 17.95pt"><span style="font-family: 宋体">是用来详细地描述当前的流（</span><span style="font-family: Arial">stream</span><span style="font-family: 宋体">）的状态。例如：是否可用，或者遇到了某种特殊的错误。这些状态信息即可以访问，也可以设置。</span></p>
<p style="text-indent: 17.95pt"><span style="font-family: 宋体">每个流对象（</span><span style="font-family: Arial">stream object</span><span style="font-family: 宋体">）都会包含一个成员（</span><span style="font-family: Arial">member</span><span style="font-family: 宋体">），这个成员通过</span><span style="font-family: Arial">setstate</span><span style="font-family: 宋体">和</span><span style="font-family: Arial">clear</span><span style="font-family: 宋体">操作进行管理。它的类型是</span><span style="font-family: Arial">iostate</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">每个</span><span style="font-family: Arial"> IO </span><span style="font-family: 宋体">类还定义了三个</span><span style="font-family: Arial"> iostate </span><span style="font-family: 宋体">类型的常量值，分别表示特定的位模式。</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: Arial">strm::badbit</span><span style="font-family: 宋体">：</span><span style="font-family: Arial">badbit </span><span style="font-family: 宋体">标志着系统级的故障，如无法恢复的读写错误。</span></p>
<p style="margin-left: 80.95pt; text-indent: -63pt"><span style="font-family: Arial">strm::failbit</span><span style="font-family: 宋体">：如果出现的是可恢复的错误，如在希望获得数值型数据时输入了字符，此时则设置</span><span style="font-family: Arial"> failbit </span><span style="font-family: 宋体">标志。</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: Arial">strm::eofbit</span><span style="font-family: 宋体">：是在遇到文件结束符时设置的，此时同时还设置了</span><span style="font-family: Arial"> failbit</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">对于</span><span style="font-family: Arial">IO</span><span style="font-family: 宋体">类的条件状态的操作，不管是查询的，</span><span style="font-family: Arial">eof(),fail(),bad(),</span><span style="font-family: 宋体">还是赋值操作，</span><span style="font-family: Arial">clear(),setstate()</span><span style="font-family: 宋体">，应该都是位操作。</span></p>
<h2>8.3 <span style="font-family: 黑体">管理输出缓冲</span> Managing the Output Buffer</h2>
<h4><span style="font-family: 新宋体">哪些条件下</span>buffer<span style="font-family: 新宋体">会被清空？</span></h4>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">The program completes normally. All output buffers are emptied as part of the return from main.</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">程序正常结束。作为</span><span style="font-family: Arial"> main </span><span style="font-family: 宋体">返回工作的一部分，将清空所有输出缓冲区。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">At some indeterminate time, the buffer can become full, in which case it will be flushed before writing the next value.</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">在一些不确定的时候，缓冲区可能已经满了，在这种情况下，缓冲区将会在写下一个值之前刷新。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">We can flush the buffer explicitly using a manipulator such as endl, flush, ends.</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">用操纵符显式地刷新缓冲区，例如行结束符</span><span style="font-family: Arial"> endl</span><span style="font-family: 宋体">。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">We can use the unitbuf manipulator to set the stream's internal state to empty the buffer after each output operation.</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">在每次输出操作执行完后，用</span><span style="font-family: Arial"> unitbuf </span><span style="font-family: 宋体">操作符设置流的内部状态，从而清空缓冲区。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">5.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">We can tie the output stream to an input stream, in which case the output buffer is flushed whenever the associated input stream is read.</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">可将输出流与输入流关联（</span><span style="font-family: Arial">tie</span><span style="font-family: 宋体">）起来。在这种情况下，在读输入流时将刷新其关联的输出缓冲区。</span></p>
<h4><span style="font-family: 新宋体">程序崩溃时，缓冲区是不会被刷新的</span></h4>
<p><span style="font-family: 宋体">前提：如果程序非正常结束，输出缓冲（</span><span style="font-family: Arial">Output buffer</span><span style="font-family: 宋体">）是不会刷新的。</span></p>
<p><span style="font-family: 宋体">建议：在每个输出都用</span><span style="font-family: Arial">endl</span><span style="font-family: 宋体">的结尾。</span></p>
<p><span style="font-family: 宋体">关于</span><span style="font-family: Arial">endl</span><span style="font-family: 宋体">和</span><span style="font-family: Arial">"n</span><span style="font-family: 宋体">的区别？</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">如果简单的从输出上看，二者肯定是没有区别的。但是</span><span style="font-family: Arial">endl</span><span style="font-family: 宋体">会刷新输出</span><span style="font-family: Arial">cout</span><span style="font-family: 宋体">的</span><span style="font-family: Arial">buffer</span><span style="font-family: 宋体">。</span></p>
<h4><span style="font-family: 新宋体">输入流和输出流绑定</span></h4>
<p><strong><span style="font-family: Arial">cin</span></strong><strong><span style="font-family: 宋体">和</span></strong><strong><span style="font-family: Arial">cout</span></strong><strong><span style="font-family: 宋体">绑定</span></strong></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">结果是：任何读输入流的尝试都将首先刷新与之绑定的输出流的缓冲区（</span><span style="font-family: Arial">buffer</span><span style="font-family: 宋体">）。：</span></p>
<table style="margin-left: 32.4pt; width: 333pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="444" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 333pt; padding-top: 0cm" valign="top" width="444">
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">cin.tie(&amp;cout);&nbsp;&nbsp; </span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">cin.tie(0); //break tie to cout, cout no longer flushed when cin is read</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">交互系统一定要保证输出流和输入流是绑定在一起的。</span></p>
<h2>8.4 <span style="font-family: 黑体">文件输入和输出</span> File Input and Output</h2>
<p><span style="font-family: Arial">fstream header</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">ifstream</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">ofstream</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">fstream</span></p>
<p><span style="font-family: 宋体">基本语法格式：</span></p>
<table style="margin-left: 32.4pt; width: 333pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="444" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 333pt; padding-top: 0cm" valign="top" width="444">
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">// construct an ifstream and bind it to the file named ifile</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">ifstream infile(ifile.c_str());</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">// ofstream output file object to write file named ofile</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">ofstream outfile(ofile.c_str());</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">注意：文件名要使用</span><span style="font-family: Arial">C</span><span style="font-family: 宋体">风格的字符串。</span></p>
<h4><span style="font-family: 新宋体">文件流可以和文件重新绑定</span></h4>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">文件流可以和文件重新绑定。但是在重新绑定前要先关闭流，并清空文件流的状态，否则上一次的文件流的状态就会是重新绑定后的初始状态。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">关闭流对象，都不可能改变流对象内部的状态。</span><span style="font-family: Arial">Closing a stream does not change the internal state of the stream object. </span></p>
<h4><span style="font-family: 新宋体">文件模式</span></h4>
<p><span style="font-family: Arial">ios_base::openmode</span></p>
<p><span style="font-family: Arial">truncate </span></p>
<p><span style="font-family: 宋体">当文件打开时清空文件的所有内容，如果使用这个属性对文件至少要有写入的权限</span></p>
<h4>Sample<span style="font-family: 新宋体">：</span></h4>
<table style="margin-left: 32.4pt; width: 333pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="444" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 333pt; padding-top: 0cm" valign="top" width="444">
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">// opens in binding it to the given file</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">ifstream&amp; open_file(ifstream &amp;in, const string &amp;file)</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">{</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; in.close();&nbsp;&nbsp;&nbsp;&nbsp; // close in case it was already open</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; in.clear();&nbsp;&nbsp;&nbsp;&nbsp; // clear any existing errors</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; // if the open fails, the stream will be in an invalid state</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; in.open(file.c_str()); // open the file we were given</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; return in; // condition state is good if open succeeded</span></p>
            <p style="margin-left: 3.55pt"><span style="font-family: Arial">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">这是一个标准的文件重新绑定的代码，包括了以上的注意事项。</span></p>
<h2>8.5 <span style="font-family: 黑体">字符串流</span>String Streams</h2>
<p><span style="font-family: 宋体">字符串流和文件流其实很类似。独有的就是利用字符串流来实现格式化输入</span><span style="font-family: Arial">/</span><span style="font-family: 宋体">输出。</span></p>
<p><span style="font-family: 宋体">输出</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: Arial">int val1 = 512, val2 = 1024;</span></p>
            <p><span style="font-family: Arial">ostringstream format_message;</span></p>
            <p><span style="font-family: Arial">// ok: converts values to a string representation</span></p>
            <p><span style="font-family: Arial">format_message &lt;&lt; "val1: " &lt;&lt; val1 &lt;&lt; ""n"</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&lt;&lt; "val2: " &lt;&lt; val2 &lt;&lt; ""n";</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">输入：</span></p>
<table style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: Arial">// str member obtains the string associated with a stringstream&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">istringstream input_istring(format_message.str());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">string dump; // place to dump the labels from the formatted message&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">// extracts the stored ascii values, converting back to arithmetic types</span></p>
            <p><span style="font-family: Arial">input_istring &gt;&gt; dump &gt;&gt; val1 &gt;&gt; dump &gt;&gt; val2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">cout &lt;&lt; val1 &lt;&lt; " " &lt;&lt; val2 &lt;&lt; endl;&nbsp;// prints 512 1024&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/amenglai/aggbug/277857.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> 2009-05-25 17:29 <a href="http://www.blogjava.net/amenglai/articles/277857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第七章 </title><link>http://www.blogjava.net/amenglai/articles/271712.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 20 May 2009 06:22:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/271712.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/271712.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/271712.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/271712.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/271712.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;7.2 Argument Passing 参数传递Reference Parameters引用形参引用形参并没有对对象进行copy，而是指向它绑定的对象。这段代码是引用形参的经典用法：                                    void swap(int &amp;v1, int &amp;v2)   ...&nbsp;&nbsp;<a href='http://www.blogjava.net/amenglai/articles/271712.html'>阅读全文</a><img src ="http://www.blogjava.net/amenglai/aggbug/271712.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> 2009-05-20 14:22 <a href="http://www.blogjava.net/amenglai/articles/271712.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第六章 </title><link>http://www.blogjava.net/amenglai/articles/271711.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 20 May 2009 06:21:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/271711.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/271711.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/271711.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/271711.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/271711.html</trackback:ping><description><![CDATA[&nbsp;
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial"><o:p>&nbsp;</o:p></span></p>
<h2><span lang="EN-US">switch</span></h2>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">switch</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">语句我用的的确不多，还是习惯写成</span><span lang="EN-US" style="font-family: Arial">if-else</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的形式。</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">switch </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">中的控制流：</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<table class="MsoNormalTable" style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 14.4pt; border-left: medium none; width: 396pt; border-bottom: medium none; border-collapse: collapse; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-alt: solid windowtext .5pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" width="528" border="1">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 396pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt" valign="top" width="528">
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">It is a common misunderstanding to expect that only the statements associated with the matched case label are executed. However, execution continues across case boundaries until the end of the switch statement or a break is encountered.<o:p></o:p></span></p>
            <p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">存在一个普遍的误解：以为程序只会执行匹配的</span><span lang="EN-US" style="font-family: Arial"> case </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">标号相关联的语句。实际上，程序从该点开始执行，并跨越</span><span lang="EN-US" style="font-family: Arial"> case </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">边界继续执行其他语句，直到</span><span lang="EN-US" style="font-family: Arial"> switch </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">结束或遇到</span><span lang="EN-US" style="font-family: Arial"> break </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">语句为止。</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">有</span><span lang="EN-US" style="font-family: Arial">2</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">种</span><span lang="EN-US" style="font-family: Arial">switch</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">常见的错误写法：</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -3pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><span lang="EN-US" style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span lang="EN-US" style="font-family: Arial">case </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">标号必须是整型常量表达式。</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -3pt; mso-list: l0 level1 lfo1; tab-stops: list 21.0pt"><span lang="EN-US" style="font-family: Wingdings; mso-bidi-font-family: Wingdings; mso-fareast-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">如果两个</span><span lang="EN-US" style="font-family: Arial"> case </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">标号具有相同的值，同样也会导致编译时的错误。</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">Switch</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">内部的变量定义：</span></p>
<p class="MsoNormal" style="margin-left: 17.95pt; mso-para-margin-left: 1.71gd"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对于</span><span lang="EN-US"> switch </span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构，只能在它的最后一个</span><span lang="EN-US"> case </span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标号或</span><span lang="EN-US"> default </span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标号后面定义变量。</span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial"><o:p>&nbsp;</o:p></span></p>
<h2><span lang="EN-US">do while</span><span style="font-family: 黑体; mso-ascii-font-family: Arial">语句</span></h2>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: Arial">用作条件判断的变量一定要定义在循环体之外，</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<table class="MsoNormalTable" style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">// repeatedly ask user for pair of numbers to sum<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">string rsp; // used in the condition; can't be defined inside the do<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">do {<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial"><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>// ...<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">} while (!rsp.empty() &amp;&amp; rsp[0] != 'n');<span style="color: green"><o:p></o:p></span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">do while </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-family: Arial">循环不可以采用如下方式定义变量：</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<table class="MsoNormalTable" style="margin-left: 32.4pt; width: 360pt; border-collapse: collapse; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes">
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">// error: declaration statement within do condition is not supported<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">do {<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>// ...<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>mumble(foo);<o:p></o:p></span></p>
            <p class="MsoNormal"><span lang="EN-US" style="font-family: Arial">} while (int foo = get_foo()); // error: declaration in do condition<span style="color: green"><o:p></o:p></span></span></p>
            </td>
        </tr>
    </tbody>
</table>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">不过其实自己写代码时，这个各色的写法一般是不会出现的。</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial"><o:p>&nbsp;</o:p></span></p>
<h2><span lang="EN-US">Using the Preprocessor for Debugging</span><span style="font-family: 黑体; mso-ascii-font-family: Arial">（使用预处理器进行调试）</span></h2>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">预处理器还定义了其余四种在调试时非常有用的常量：</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 17.95pt; mso-para-margin-left: 1.71gd"><span lang="EN-US" style="font-family: Arial">__FILE__ </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文件名</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 17.95pt; mso-para-margin-left: 1.71gd"><span lang="EN-US" style="font-family: Arial">__LINE__ </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">当前行号</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 17.95pt; mso-para-margin-left: 1.71gd"><span lang="EN-US" style="font-family: Arial">__TIME__ </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文件被编译的时间</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 17.95pt; mso-para-margin-left: 1.71gd"><span lang="EN-US" style="font-family: Arial">__DATE__ </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文件被编译的日期</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">断言</span><span lang="EN-US" style="font-family: Arial">assert</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">是一种预处理宏，</span><span lang="EN-US" style="font-family: Arial">assert </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">宏就求解条件表达式，如果结果为</span><span lang="EN-US" style="font-family: Arial"> false</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">，</span><span lang="EN-US" style="font-family: Arial">assert </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">输出信息并且终止程序的执行。如果该表达式有一个非零（例如，</span><span lang="EN-US" style="font-family: Arial">true</span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">）值，则</span><span lang="EN-US" style="font-family: Arial"> assert </span><span style="font-family: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">不做任何操作。</span><span lang="EN-US" style="font-family: Arial"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: Arial"><o:p>&nbsp;</o:p></span></p>
<img src ="http://www.blogjava.net/amenglai/aggbug/271711.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> 2009-05-20 14:21 <a href="http://www.blogjava.net/amenglai/articles/271711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第五章 </title><link>http://www.blogjava.net/amenglai/articles/271709.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 20 May 2009 06:19:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/271709.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/271709.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/271709.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/271709.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/271709.html</trackback:ping><description><![CDATA[&nbsp;
<h2>5.3 <span style="font-family: 黑体">位操作符</span>(The Bitwise Operators)</h2>
<p><span style="font-family: 宋体">尽量不要使用<strong>符号数</strong>进行位运算，因为符号位的处理和机器有关。</span></p>
<p><span style="font-family: 宋体">对</span><span style="font-family: Arial">XOR</span><span style="font-family: 宋体">的描述真是简单明了，</span><span style="font-family: Arial">For each bit position, the result is 1 if either but not both operands contain 1; Otherwise, the result is 0.</span></p>
<p><span style="font-family: 宋体">输入输出标准库重载了移位操作符</span><span style="font-family: Arial">&gt;&gt;</span><span style="font-family: 宋体">和</span><span style="font-family: Arial">&lt;&lt;</span><span style="font-family: 宋体">用于输入和输出。</span></p>
<h2><span style="font-family: 黑体">复合表达式的求值（</span>Evaluating Compound Expressions<span style="font-family: 黑体">）</span></h2>
<p><span style="font-family: 宋体">这里面有两个关键词：</span></p>
<p style="margin-left: 48pt; text-indent: -21pt; tab-stops: list 48.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">Precedence </span></p>
<p style="margin-left: 45pt"><span style="font-family: Arial">Precedence specifies how the operands are grouped.</span><span style="font-family: 宋体">优先级规定的是操作数的结合方式</span></p>
<p style="margin-left: 48pt; text-indent: -21pt; tab-stops: list 48.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">associativity</span></p>
<p style="margin-left: 44.95pt"><span style="font-family: Arial">Associativity specifies how to group operators at the same precedence level.</span><span style="font-family: 宋体">结合性规定了具有相同优先级的操作符如何分组。</span></p>
<p style="margin-left: 44.95pt"><span style="font-family: 宋体">例如：</span></p>
<p style="margin-left: 44.95pt"><span style="font-family: 宋体">赋值操作符是右关联</span></p>
<table style="margin-left: 45.35pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #cccccc; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm" valign="top" width="568">
            <p><span style="font-family: Arial">&nbsp;ival = jval = kval = lval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // right associative</span></p>
            <p><span style="font-family: Arial">&nbsp;(ival = (jval = (kval = lval))) // equivalent, parenthesized version</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 44.95pt"><span style="font-family: 宋体">算数操作符是左关联</span></p>
<table style="margin-left: 45.35pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #cccccc; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm" valign="top" width="568">
            <p><span style="font-family: Arial">ival * jval / kval * lval&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // left associative</span></p>
            <p><span style="font-family: Arial">(((ival * jval) / kval) * lval) // equivalent, parenthesized version</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h2>5.4 <span style="font-family: 黑体">赋值操作符（</span>Assignment Operators<span style="font-family: 黑体">）</span></h2>
<p><span style="font-family: 宋体">让你不得不佩服，</span><span style="font-family: Arial">Lippman</span><span style="font-family: 宋体">这样的大师仅仅赋值操作符（</span><span style="font-family: Arial">Assignment Operators</span><span style="font-family: 宋体">）就可以讲出这么多的内容。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">赋值运算是右关联，它的返回值是左操作数；类型为左操作数的类型（</span><span style="font-family: Arial">The result of an assignment is the left-hand operand, the type of the result is the type of the left-hand operand.</span><span style="font-family: 宋体">）。</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">这样就好理解这样的赋值语句了：</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">先执行</span><span style="font-family: Arial">jval = 0;</span><span style="font-family: 宋体">返回值是</span><span style="font-family: Arial">jval </span><span style="font-family: 宋体">，再执行</span><span style="font-family: Arial">ival = jval</span><span style="font-family: 宋体">。</span></p>
<table style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 23.4pt; border-left: medium none; width: 387pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 387pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="516">
            <p><span style="font-family: Arial">int ival, jval;</span></p>
            <p><span style="font-family: Arial">ival = jval = 0; // ok: each assigned 0</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">赋值操作的优先级低。</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">下面的条件语句返回值是</span><span style="font-family: Arial">true</span><span style="font-family: 宋体">，因为先执行赋值语句，返回值是</span><span style="font-family: Arial">i</span><span style="font-family: 宋体">，</span><span style="font-family: Arial">i</span><span style="font-family: 宋体">大于</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">，因此条件语句判断为</span><span style="font-family: Arial">true</span><span style="font-family: 宋体">。</span></p>
<table style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 23.4pt; border-left: medium none; width: 387pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 387pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="516">
            <p><span style="font-family: Arial">if (i = 42)</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">下面的条件语句返回值是</span><span style="font-family: Arial">false</span><span style="font-family: 宋体">，因为先执行赋值语句，返回值是</span><span style="font-family: Arial">i</span><span style="font-family: 宋体">，</span><span style="font-family: Arial">i</span><span style="font-family: 宋体">等于</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">，因此条件语句判断为</span><span style="font-family: Arial">false</span><span style="font-family: 宋体">。</span></p>
<table style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 23.4pt; border-left: medium none; width: 387pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 387pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="516">
            <p><span style="font-family: Arial">if (i = 0)</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h2>5.5 Increment and Decrement Operators<span style="font-family: 黑体">自增和自减操作符</span></h2>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-family: 宋体">重点</span></strong></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">前置和后置操作符</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-family: 宋体">建议</span></strong></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">只在必要的时候才使用后置操作符。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-family: 宋体">区别</span></strong></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">前置和后置操作符的返回值是不同的，这是最重要的区别，也是理解的基础。</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">前置操作符：值加</span><span style="font-family: Arial">1</span><span style="font-family: 宋体">，再返回。（</span><span style="font-family: Arial">It increments the value and returns the incremented version.</span><span style="font-family: 宋体">）</span></p>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">后置操作符：必须保留原始值，（原始值加</span><span style="font-family: Arial">1</span><span style="font-family: 宋体">）返回的结果是未增加的值。（</span><span style="font-family: Arial">The postfix operator must store the original value so that it can return the unincremented value as its result.</span><span style="font-family: 宋体">）</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><strong><span style="font-family: 宋体">代码</span></strong></p>
<p style="margin-left: 17.95pt"><span style="font-family: Arial">cnt—</span><span style="font-family: 宋体">的返回值是</span><span style="font-family: Arial">cnt</span><span style="font-family: 宋体">。</span></p>
<table style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 23.4pt; border-left: medium none; width: 387pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 387pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="516">
            <p><span style="font-family: Arial">vector&lt;int&gt; ivec;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // empty vector</span></p>
            <p><span style="font-family: Arial">int cnt = 10;</span></p>
            <p><span style="font-family: Arial">// add elements 10...1 to ivec</span></p>
            <p><span style="font-family: Arial">while (cnt &gt; 0)</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; ivec.push_back(cnt--);&nbsp;// int postfix decrement</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 17.95pt"><span style="font-family: Arial">*iter++</span><span style="font-family: 宋体">就是</span><span style="font-family: Arial">*(iter++)</span><span style="font-family: 宋体">，</span><span style="font-family: Arial">++</span><span style="font-family: 宋体">操作的优先级高于</span><span style="font-family: Arial">*</span><span style="font-family: 宋体">，所以先执行</span><span style="font-family: Arial">iter++</span><span style="font-family: 宋体">，这个操作的返回值是</span><span style="font-family: Arial">iter</span><span style="font-family: 宋体">，然后</span><span style="font-family: Arial">iter+1.</span><span style="font-family: 宋体">再执行解引用操作</span><span style="font-family: Arial">*</span><span style="font-family: 宋体">，这个解引用操作的操作数是返回的</span><span style="font-family: Arial">iter</span><span style="font-family: 宋体">。</span></p>
<table style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 23.4pt; border-left: medium none; width: 387pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 387pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="516">
            <p><span style="font-family: Arial">vector&lt;int&gt;::iterator iter = ivec.begin();</span></p>
            <p><span style="font-family: Arial">// prints 10 9 8 ... 1</span></p>
            <p><span style="font-family: Arial">while (iter != ivec.end())</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; cout &lt;&lt; *iter++ &lt;&lt; endl; // iterator postfix increment</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: Arial">Sizeof</span></p>
<p><span style="font-family: 宋体">？如果是返回对象的</span><span style="font-family: Arial">size</span><span style="font-family: 宋体">，那么</span><span style="font-family: Arial">sizeof</span><span style="font-family: 宋体">的返回值是不是和数据有关？</span></p>
<p><span style="color: blue; font-family: 宋体">赋值顺序</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="color: blue; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: blue; font-family: Arial">&amp;&amp; </span><span style="color: blue; font-family: 宋体">和</span><span style="color: blue; font-family: Arial"> || </span><span style="color: blue; font-family: 宋体">操作符计算其操作数的次序：当且仅当其右操作数确实影响了整个表达式的值时，才计算这两个操作符的右操作数。</span></p>
<p style="margin-left: 17.95pt"><span style="color: blue; font-family: Arial">&amp;&amp; and || operators specify the order in which their operands are evaluated: In both cases the right-hand operand is evaluated if and only if doing so might affect the truth value of the overall expression.</span></p>
<p style="margin-left: 17.95pt"><span style="color: blue; font-family: 宋体">（这句话说的真是严谨。）</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="color: blue; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: blue; font-family: 宋体">一个表达式里，不要在两个或更多的子表达式中对同一对象做自增或自减操作。</span></p>
<p>Do not use an increment or decrement operator on the same object in more than two subexpressions of the same expression.</p>
<h2><span style="color: blue">5.11 new </span><span style="color: blue; font-family: 黑体">和</span><span style="color: blue"> delete </span><span style="color: blue; font-family: 黑体">表达式（</span>The new and delete Expressions<span style="font-family: 黑体">）</span></h2>
<p><span style="color: blue; font-family: Arial">new</span><span style="color: blue; font-family: 宋体">表达式返回的是一个指针，这个指针指向新分配的一个对象。</span></p>
<table style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 23.4pt; border-left: medium none; width: 387pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 387pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="516">
            <p><span style="font-family: Arial">int *pi = new int;&nbsp;// pi points to dynamically allocated,</span></p>
            <p><span style="font-family: Arial">delete pi;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="color: blue; font-family: 宋体">但是这样写就不是动态分配的指针</span></p>
<table style="border-right: medium none; border-top: medium none; background: #cccccc; margin-left: 23.4pt; border-left: medium none; width: 387pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="516" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 387pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="516">
            <p><span style="font-family: Arial">int i;</span></p>
            <p><span style="font-family: Arial">int *pi = &amp;i;</span></p>
            <p><span style="font-family: Arial">delete pi; //</span><span style="font-family: 宋体">因为</span><span style="font-family: Arial">pi</span><span style="font-family: 宋体">指向的是一个</span><span style="font-family: Arial">local</span><span style="font-family: 宋体">变量</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="color: blue; font-family: 宋体">后面的写法是不能执行</span><span style="color: blue; font-family: Arial">delete</span><span style="color: blue; font-family: 宋体">表达式的。</span></p>
<p><span style="color: blue; font-family: 宋体">由</span><span style="color: blue; font-family: Arial">new</span><span style="color: blue; font-family: 宋体">动态创建的对象一定要执行</span><span style="color: blue; font-family: Arial">delete</span><span style="color: blue; font-family: 宋体">来删除。否则内存就会被耗尽。</span></p>
<p><span style="color: blue; font-family: 宋体">大师给了以下的建议：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="color: blue; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: blue; font-family: Arial">Setting the pointer to 0 after the object it refers to has been deleted makes it clear that the pointer points to no object.</span><span style="color: blue; font-family: 宋体">（一旦删除了指针所指向的对象，立即将指针置为</span><span style="color: blue; font-family: Arial"> 0</span><span style="color: blue; font-family: 宋体">，这样就非常清楚地表明指针不再指向任何对象。）</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="color: blue; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: blue; font-family: Arial">Reading</span><span style="color: blue; font-family: Arial"> or writing to the object after it has been deleted. This error can sometimes be detected by setting the pointer to 0 after deleting the object to which the pointer had pointed.</span><span style="color: blue; font-family: 宋体">（读写已删除的对象。如果删除指针所指向的对象之后，将指针置为</span><span style="color: blue; font-family: Arial"> 0 </span><span style="color: blue; font-family: 宋体">值，则比较容易检测出这类错误。）</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="color: blue; font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: blue; font-family: Arial">Applying a delete expression to the same memory location twice. This error can happen when two pointers address the same dynamically allocated object. If delete is applied to one of the pointers, then the object's memory is returned to the free store. If we subsequently delete the second pointer, then the free store may be corrupted.</span><span style="color: blue; font-family: 宋体">（对同一个内存空间使用两次</span><span style="color: blue; font-family: Arial"> delete </span><span style="color: blue; font-family: 宋体">表达式。当两个指针指向同一个动态创建的对象，删除时就会发生错误。如果在其中一个指针上做</span><span style="color: blue; font-family: Arial"> delete </span><span style="color: blue; font-family: 宋体">运算，将该对象的内存空间返还给自由存储区，然后接着</span><span style="color: blue; font-family: Arial"> delete </span><span style="color: blue; font-family: 宋体">第二个指针，此时则自由存储区可能会被破坏。）</span></p>
<img src ="http://www.blogjava.net/amenglai/aggbug/271709.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> 2009-05-20 14:19 <a href="http://www.blogjava.net/amenglai/articles/271709.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ Primer 之 读书笔记 第四章</title><link>http://www.blogjava.net/amenglai/articles/269168.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Wed, 06 May 2009 01:59:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/269168.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/269168.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/269168.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/269168.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/269168.html</trackback:ping><description><![CDATA[&nbsp;
<p style="text-align: center" align="center"><strong><span style="font-size: 14pt; font-family: 宋体">第四章</span></strong><strong><span style="font-size: 14pt; font-family: 宋体">数组和指针</span></strong></p>
<p style="text-align: center" align="center"><strong><span style="font-size: 14pt; font-family: Arial">Arrays and Points</span></strong></p>
<p><span style="font-family: Arial">vector</span><span style="font-family: 宋体">和</span><span style="font-family: Arial">array</span><span style="font-family: 宋体">类似的地方就是它们都是同一对象类型的集合。不同点是</span><span style="font-family: Arial">array</span><span style="font-family: 宋体">是固定长度的。</span><span style="font-family: Arial">iterator</span><span style="font-family: 宋体">之于</span><span style="font-family: Arial">vector</span><span style="font-family: 宋体">就如同指针之于</span><span style="font-family: Arial">array</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 新宋体">使用指针的一个重要原因是</span><span style="font-family: Arial">vector</span><span style="font-family: 新宋体">不能提供所需的访问速度。</span></p>
<p><span style="font-family: 新宋体">数组类型不能是引用（</span><span style="font-family: Arial">reference</span><span style="font-family: 新宋体">）</span></p>
<h2><span style="color: blue">4.1 Array</span></h2>
<p><span style="font-family: 新宋体">关于</span><span style="font-family: Arial">Array</span><span style="font-family: 新宋体">初始化：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 新宋体">使用</span><span style="font-family: Arial">class</span><span style="font-family: 新宋体">默认的构造函数初始化每个单元。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">Character Array</span><span style="font-family: 新宋体">即可以用字符数组来初始化也可以用</span><span style="font-family: Arial">string</span><span style="font-family: 新宋体">来初始化，注意如果用</span><span style="font-family: Arial">string</span><span style="font-family: 新宋体">，那么自动在末尾追加了</span><span style="font-family: Arial">null</span><span style="font-family: 新宋体">作为结束符，这样数组的长度</span><span style="font-family: Arial">+1.</span></p>
<p><span style="font-family: 新宋体">下标操作时，要使用数据类型是：</span><strong><em><span style="font-family: Arial">size_t</span></em></strong><em><span style="font-family: Arial">,</span></em><span style="font-family: 新宋体">就像在</span><span style="font-family: Arial">vector</span><span style="font-family: 新宋体">中使用</span><span style="font-family: Arial">size_type</span><span style="font-family: 新宋体">。</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 329.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="439">
            <p><em><span style="font-family: Arial">for (size_t ix = 0; ix != array_size; ++ix)</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ia[ix] = ix;</span></em></p>
            </td>
        </tr>
    </tbody>
</table>
<h2><span style="color: blue">4.2 Pointers</span></h2>
<h3><span style="font-family: 宋体">什么是指针</span></h3>
<p><span style="font-family: Arial">Pointers are iterators for arrays.</span><span style="font-family: 宋体">指针是用于数组的迭代器。</span></p>
<p><span style="font-family: Arial">pointer holds the address of another object:</span><span style="font-family: 宋体">。具体来说，指针保存的是另一个对象的地址。</span></p>
<table style="background: silver; margin-left: 17.95pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 320.45pt; padding-top: 0cm" valign="top" width="427">
            <p><span style="font-family: Arial">string *sp = &amp;s; // sp holds the address of s</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: Arial">*sp</span><span style="font-family: 宋体">里面</span><span style="font-family: Arial">*</span><span style="font-family: 宋体">代表</span><span style="font-family: Arial">sp</span><span style="font-family: 宋体">是一个指针。</span></p>
<p><span style="font-family: Arial">Best practice</span><span style="font-family: 宋体">：指针初始化时，如果不能指向具体的地址，就设置为</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">，这样在程序中就可以检测出指针没有指向一个对象（</span><span style="font-family: Arial">object</span><span style="font-family: 宋体">）。</span></p>
<p><span style="font-family: 宋体">指针初始化和赋值操作的约束</span></p>
<p><span style="font-family: 宋体">指针初始化和赋值</span></p>
<p><span style="font-family: 宋体">只有</span><span style="font-family: Arial">4</span><span style="font-family: 宋体">类值可以初始化指针和指针赋值：</span></p>
<p style="margin-left: 27pt; text-indent: -9pt; tab-stops: list 27.0pt"><span style="font-family: Arial">1.</span><span style="font-family: 宋体">值为</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">的常量表达式。不能把任何的</span><span style="font-family: Arial">int</span><span style="font-family: 宋体">赋值给指针，即使这个</span><span style="font-family: Arial">int</span><span style="font-family: 宋体">的值是</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">，但是可以把值是</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">的</span><span style="font-family: Arial">const </span><span style="font-family: 宋体">或者数值</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">赋值给指针。</span><strong><span style="font-family: Arial">NULL</span></strong><span style="font-family: 宋体">定义为</span><span style="font-family: Arial">0</span><span style="font-family: 宋体">，所以也可以使用。</span><strong><span style="font-family: Arial">NULL</span></strong><span style="font-family: 宋体">叫做预处理变量。</span></p>
<table style="border-right: medium none; border-top: medium none; margin-left: 23.4pt; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 320.35pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="427">
            <p><span style="font-family: Arial">int *pi = NULL</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 27pt; text-indent: -9pt; tab-stops: list 27.0pt"><span style="font-family: Arial">2.</span><span style="font-family: 宋体">类型匹配的对象的地址</span></p>
<p style="margin-left: 27pt; text-indent: -9pt; tab-stops: list 27.0pt"><span style="font-family: Arial">3.</span><span style="font-family: 宋体">另一对象末的下一地址</span></p>
<p style="margin-left: 27pt; text-indent: -9pt; tab-stops: list 27.0pt"><span style="font-family: Arial">4.</span><span style="font-family: 宋体">同类型的其它有效的指针</span></p>
<p><em><span style="font-family: Arial">void*</span></em><span style="font-family: 宋体">指针，这是一个特殊类型的指针，它能够是任何对象的地址。它就是说明它的值是一个指针，但是指针所指向的对象的类型是不可知的。</span></p>
<p><span style="font-family: 宋体">因此</span><em><span style="font-family: Arial">void*</span></em><span style="font-family: 宋体">指针只能执行通用的操作：</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">指针比较</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">传递给</span><span style="font-family: Arial">function</span><span style="font-family: 宋体">或者作为</span><span style="font-family: Arial">function</span><span style="font-family: 宋体">的返回值。</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">赋值给另一个</span><em><span style="font-family: Arial">void*</span></em><span style="font-family: 宋体">指针</span></p>
<h3>Operations on Pointer<span style="font-family: 宋体">（指针操作）</span></h3>
<p><span style="font-family: 宋体">注意</span><span style="font-family: Arial">*</span><span style="font-family: 宋体">在这里是一个</span><span style="font-family: Arial">operator</span><span style="font-family: 宋体">。</span><span style="font-family: Arial">dereference a pointer</span><span style="font-family: 宋体">。解引用操作（</span><span style="font-family: Arial">dereference operator</span><span style="font-family: 宋体">）返回指定对象的左值</span><span style="font-family: Arial">lvalue</span><span style="font-family: 宋体">。因此可以进行赋值操作。</span></p>
<p><span style="font-family: 宋体">引用和指针的区别：</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Arial">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">引用总是指向对象</span><span style="font-family: Arial">object</span><span style="font-family: 宋体">。引用必须初始化，但指针是可以仅仅定义，而无需初始化的。</span></p>
<p style="margin-left: 38.95pt; text-indent: -21pt; tab-stops: list 38.95pt"><span style="font-family: Arial">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">赋值：引用的赋值会改变引用所绑定的对象的值；引用是不能重新绑定新的对象的。一旦初始化，引用总是指向同一个对象。</span></p>
<p style="margin-left: 36pt"><span style="font-family: 宋体">引用：</span></p>
<table style="margin-left: 50.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: Arial">int &amp;ri = ival, &amp;ri2 = ival2;</span></p>
            <p><span style="font-family: Arial">ri = ri2;&nbsp;&nbsp;&nbsp; // assigns ival2 to ival</span><span style="color: green; font-family: 宋体">这里</span><span style="color: green; font-family: Arial">ri</span><span style="color: green; font-family: 宋体">和</span><span style="color: green; font-family: Arial">ri2</span><span style="color: green; font-family: 宋体">还是指向</span><span style="color: green; font-family: Arial">2</span><span style="color: green; font-family: 宋体">个不同的地址单元</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 36pt"><span style="font-family: 宋体">指针：</span></p>
<table style="margin-left: 50.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><span style="font-family: Arial">int ival = 1024, ival2 = 2048;</span></p>
            <p><span style="font-family: Arial">int *pi = &amp;ival, *pi2 = &amp;ival2;</span></p>
            <p><span style="font-family: Arial">pi = pi2;&nbsp;&nbsp;&nbsp; // pi now points to ival2</span><span style="font-family: 宋体">，</span><span style="color: green; font-family: Arial">pi</span><span style="color: green; font-family: 宋体">和</span><span style="color: green; font-family: Arial">pi2</span><span style="color: green; font-family: 宋体">都指向了同一个地址单元</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">指向指针的指针</span><span style="font-family: Arial">**ppi</span><span style="font-family: 宋体">，代码：</span></p>
<table style="margin-left: 50.4pt; width: 13cm; border-collapse: collapse" cellspacing="0" cellpadding="0" width="491" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 13cm; padding-top: 0cm" valign="top" width="491">
            <p><span style="font-family: Arial">int ival=1024;</span></p>
            <p><span style="font-family: Arial">int *pi = &amp;ival;</span></p>
            <p><span style="font-family: Arial">int **ppi=&amp;pi;</span></p>
            <p><span style="font-family: Arial">int *pi2 =*ppi; //</span><span style="color: green; font-family: 宋体">或者</span><span style="color: green; font-family: Arial"> int *pi2 = pi;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">对</span><span style="font-family: Arial">ppi</span><span style="font-family: 宋体">解引用</span><span style="font-family: Arial">2</span><span style="font-family: 宋体">次，就可以得到</span><span style="font-family: Arial">ival</span><span style="font-family: 宋体">的值了。</span></p>
<h4>1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">使用指针访问数组单元</span></h4>
<p><span style="font-family: 宋体">当使用数组的名字时，这个名字就自动转换为指向数组第一个单元的指针。</span></p>
<table style="margin-left: 50.4pt; width: 369pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="492" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 369pt; padding-top: 0cm" valign="top" width="492">
            <p style="margin-left: 11.35pt"><span style="font-family: Arial">int ia[] = {0,2,4,6,8};</span></p>
            <p style="margin-left: 11.35pt"><span style="font-family: Arial">int *ip = ia; // ip points to ia[0] </span><span style="color: green; font-family: 宋体">定义</span><span style="color: green; font-family: Arial">ip</span><span style="color: green; font-family: 宋体">是指针，赋值为</span><span style="color: green; font-family: Arial">ia</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">指针的算数运算会产生一个新指针。</span></p>
<p><span style="font-family: 宋体">两指针相减得到的数据类型是</span><em><span style="font-family: Arial">ptrdiff_t</span></em><span style="font-family: 宋体">。它是一个</span></p>
<table style="margin-left: 41.95pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 375.65pt; padding-top: 0cm" valign="top" width="501">
            <p><span style="font-family: Arial">int last = *(ia + 4); // ok: initializes last to 8, the value of ia[4]</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">如何获得一个数组的结尾？</span></p>
<table style="background: #cccccc; margin-left: 41.4pt; width: 360pt; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 360pt; padding-top: 0cm" valign="top" width="480">
            <p><em><span style="font-family: Arial">const size_t arr_size = 5;</span></em></p>
            <p><em><span style="font-family: Arial">int arr[arr_size] = {1,2,3,4,5};</span></em></p>
            <p><em><span style="font-family: Arial">int *p = arr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ok: p points to arr[0]</span></em></p>
            <p><em><span style="font-family: Arial">int *p2 = p + arr_size; // ok: p2 points one past the end of arr</span></em></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: Arial">p2</span><span style="font-family: 宋体">就是指向了数组的结尾。</span></p>
<h3><span style="font-family: 宋体">指向</span>const<span style="font-family: 宋体">对象的指针和</span>const<span style="font-family: 宋体">指针</span></h3>
<h4>1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">指向</span>const<span style="font-family: 宋体">对象的指针</span></h4>
<p><span style="font-family: 宋体">如果指针指向的是一个</span><span style="font-family: Arial">const</span><span style="font-family: 宋体">对象，那么肯定不希望它能够修改这个</span><span style="font-family: Arial">const</span><span style="font-family: 宋体">对象的值。那么这样的指针如何定义？</span></p>
<table style="margin-left: 41.95pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm" valign="top" width="568">
            <p><span style="font-family: Arial">const double *cptr; //<span style="color: green">cptr</span></span><span style="color: green; font-family: 宋体">是指向</span><span style="color: green; font-family: Arial">const double</span><span style="color: green; font-family: 宋体">类型的指针</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">对于这个定义的理解是这样子的：</span></p>
<p style="margin-left: 29.9pt; text-indent: -21pt; tab-stops: list 29.9pt"><span style="font-family: Arial">A.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">这里的限定词（</span><span style="font-family: Arial">qualifier</span><span style="font-family: 宋体">）</span><span style="font-family: Arial">-const</span><span style="font-family: 宋体">是限定</span><span style="font-family: Arial">cptr</span><span style="font-family: 宋体">指向的数据类型必须是</span><span style="font-family: Arial">const double</span><span style="font-family: 宋体">，而不是限定</span><span style="font-family: Arial">cptr</span><span style="font-family: 宋体">本身。</span></p>
<p style="margin-left: 29.9pt; text-indent: -21pt; tab-stops: list 29.9pt"><span style="font-family: Arial">B.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: Arial">cptr</span><span style="font-family: 宋体">本身不是</span><span style="font-family: Arial">const</span></p>
<p style="margin-left: 29.9pt; text-indent: -21pt; tab-stops: list 29.9pt"><span style="font-family: Arial">C.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">不能做的是用</span><span style="font-family: Arial">cptr</span><span style="font-family: 宋体">去修改它指向的对象的值</span></p>
<p><span style="font-family: 宋体">但是也可以把指向</span><span style="font-family: Arial">const</span><span style="font-family: 宋体">对象的指针赋值为非</span><span style="font-family: Arial">const</span><span style="font-family: 宋体">对象的地址。（</span><span style="font-family: Arial">A pointer to a const object can be assigned the address of a nonconst object</span><span style="font-family: 宋体">）</span></p>
<table style="margin-left: 41.95pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm" valign="top" width="568">
            <p><span style="font-family: Arial">int val=10;</span></p>
            <p><span style="font-family: Arial">const int *cptr = &amp;val;</span></p>
            <p><span style="font-family: Arial">val=30;&nbsp;&nbsp; //</span><span style="font-family: 宋体">这样写是对的</span></p>
            <p><span style="font-family: Arial">*cptr = 30; //</span><span style="font-family: 宋体">这样写会死人的</span><em><span style="font-family: Wingdings">L</span></em></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">不过我想，这只不过是代码上的文字游戏而已，如果程序这样写，也许会死人的。混乱！</span></p>
<p><span style="font-family: 宋体">这种指针的用途是作为方法的参数，这可以保证这个参数不会在方法中被修改。（哎，要不怎么说是大师呢，佩服！）</span></p>
<h4>2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>const<span style="font-family: 宋体">指针</span></h4>
<p><span style="font-family: Arial">const</span><span style="font-family: 宋体">指针的值是不可以修改的，但是</span><span style="font-family: Arial">const</span><span style="font-family: 宋体">指针指向的对象的值是可以修改的。</span></p>
<table style="margin-left: 41.95pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm" valign="top" width="568">
            <p><span style="font-family: Arial">int errNumb = 0;</span></p>
            <p><span style="font-family: Arial">int *const curErr = &amp;errNumb; // curErr is a constant pointer</span></p>
            <p><span style="font-family: Arial">*curErr = 0; // ok: reset value of the object to which curErr is bound</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h4>3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">指针和</span>typedef</h4>
<p><span style="font-family: 宋体">复习：</span></p>
<p style="margin-left: 27pt"><span style="font-family: Arial">typedef </span><span style="font-family: 宋体">可以用来定义类型的同义词。</span><span style="font-family: Arial">wages</span><span style="font-family: 宋体">就是</span><span style="font-family: Arial">double</span><span style="font-family: 宋体">的同义词</span></p>
<table style="margin-left: 32.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 375.65pt; padding-top: 0cm" valign="top" width="501">
            <p><span style="font-family: Arial">typedef double wages;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;wages is a synonym for double</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">（以下的这段很饶人啊）</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">typedef string *pstring; //<span style="color: green">pstring</span></span><span style="color: green; font-family: 宋体">是</span><span style="color: green; font-family: Arial">string</span><span style="color: green; font-family: 宋体">的同义词；并且</span><span style="color: green; font-family: Arial">pstring</span><span style="color: green; font-family: 宋体">是指针类型</span></p>
            <p><span style="font-family: Arial">const pstring cstr; //</span><span style="color: green; font-family: 宋体">这是指向</span><span style="color: green; font-family: Arial">string</span><span style="color: green; font-family: 宋体">的</span><span style="color: green; font-family: Arial">const</span><span style="color: green; font-family: 宋体">指针，而不是指向</span><span style="color: green; font-family: Arial">const string</span><span style="color: green; font-family: 宋体">的指针</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">第一绕：</span><span style="font-family: Arial">pstring</span><span style="font-family: 宋体">类型是指向</span><span style="font-family: Arial">string</span><span style="font-family: 宋体">类型的指针类型。</span></p>
<p><span style="font-family: 宋体">第二绕：</span><span style="font-family: Arial">const</span><span style="font-family: 宋体">是用来修饰</span><span style="font-family: Arial">pstring</span><span style="font-family: 宋体">类型的，</span><strong><em><span style="font-family: Arial">const pstring</span></em></strong><span style="font-family: 宋体">就是</span><span style="font-family: Arial">const</span><span style="font-family: 宋体">的</span><span style="font-family: Arial">string</span><span style="font-family: 宋体">指针</span></p>
<p style="margin-left: 44.95pt; text-indent: -44.95pt"><span style="font-family: 宋体">第三绕：这不存在简单的文字替换的游戏：</span><em><span style="font-family: Arial">const pstring cstr;</span></em><span style="font-family: 宋体">等于</span><em><span style="font-family: Arial">const string* cstr;</span></em><span style="font-family: 宋体">所以就是指向</span><span style="font-family: Arial">const string</span><span style="font-family: 宋体">的指针。错误！</span></p>
<h2>4.3 C<span style="font-family: 黑体">风格字符串</span></h2>
<p><span style="font-family: 宋体">不建议在</span><span style="font-family: Arial">C++</span><span style="font-family: 宋体">中使用</span><span style="font-family: Arial">C</span><span style="font-family: 宋体">风格的字符串，原因是它有&#8220;</span><span style="font-family: Arial">many many</span><span style="font-family: 宋体">&#8221;的安全问题。</span></p>
<h4>1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">什么是</span>C<span style="font-family: 宋体">风格的字符串？</span></h4>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">它不是一种类型，而是以空字符</span><span style="font-family: Arial"> <strong>null </strong></span><strong><span style="font-family: 宋体">结束</span></strong><span style="font-family: 宋体">的字符数组。</span></p>
<p><span style="font-family: 宋体">定义：</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">char ca2[] = {'C', '+', '+', '"0'};&nbsp;// explicit null</span></p>
            <p><span style="font-family: Arial">char ca3[] = "C++";&nbsp;&nbsp;&nbsp;&nbsp; // null terminator added automatically</span></p>
            <p><span style="font-family: Arial">const char *cp = "C++"; // null terminator added automatically</span></p>
            <p><span style="font-family: Arial">char *cp2 = ca2;&nbsp;&nbsp; // points to first element of a null-terminated char array</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">遍历字符串</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">const char *cp = "some value";</span></p>
            <p><span style="font-family: Arial">while (*cp) {</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; // do something to *cp</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp; ++cp;</span></p>
            <p><span style="font-family: Arial">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h4>2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">字符串函数</span></h4>
<p><span style="font-family: Arial">C</span><span style="font-family: 宋体">标准库提供了一系列的字符串函数，但是这些函数都不检查参数的合法性（限制条件）。这就是</span><span style="font-family: Arial">Lippman</span><span style="font-family: 宋体">不建议在</span><span style="font-family: Arial">C++</span><span style="font-family: 宋体">中使用</span><span style="font-family: Arial">C</span><span style="font-family: 宋体">风格的字符串的原因。</span></p>
<p><span style="font-family: 宋体">主要的限制：</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">传递给这些标准库函数的指针必须是非空的。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">每个指针必须是以</span><span style="font-family: Arial">null</span><span style="font-family: 宋体">结尾的。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">数组的长度要足够大</span></p>
<p><span style="font-family: Arial">strlen(s)</span><span style="font-family: 宋体">，返回的是</span><span style="font-family: Arial">s</span><span style="font-family: 宋体">的长度，但是这里并不包含</span><span style="font-family: Arial">null</span><span style="font-family: 宋体">，因此数组的实际长度是</span><span style="font-family: Arial">strlen(s)+1</span><span style="font-family: 宋体">。</span></p>
<h4>3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">使用动态数组</span></h4>
<p><span style="font-family: 宋体">为什么要使用动态数组？</span></p>
<p><span style="font-family: 宋体">通常是因为在编译时无法知道数组的维数，所以才需要动态创建该数组。</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">size_t n = get_size(); // get_size returns number of elements needed</span></p>
            <p><span style="font-family: Arial">int* p = new int[n];</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">如果是普通的定义数组，以上的定义是根本无法实现的，因为在编译期是不能确定数组的大小的。只能这样定义：</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">const n=45;</span></p>
            <p><span style="font-family: Arial">int p[n];</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">因此就可以得出结论：动态数组主要是用于当数组的尺寸不能在编译期确定的情况。</span></p>
<p><span style="font-family: 宋体">数组释放：</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">delete [] p ;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<h4>4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">疑问代码（</span>P139<span style="font-family: 宋体">）：</span></h4>
<p><span style="font-family: 宋体">我认为在</span><em><span style="color: red; font-family: Arial">const size_t len = strlen(pc +1); </span></em><span style="font-family: Arial">&nbsp;</span><span style="font-family: 宋体">这行存在笔误，应该是</span></p>
<p><em><span style="color: blue; font-family: Arial">const size_t len = strlen(pc )+1;</span></em></p>
<p><span style="font-family: 宋体">否则</span><span style="font-family: Arial">copy</span><span style="font-family: 宋体">后得到的结果</span><span style="font-family: Arial">pc2</span><span style="font-family: 宋体">不是</span><span style="font-family: Arial">C</span><span style="font-family: 宋体">风格的字符串，因为最后一个单元的内容是</span><span style="font-family: Arial">&#8217;g&#8217;</span><span style="font-family: 宋体">而不是</span><span style="font-family: Arial">null</span><span style="font-family: 宋体">。</span></p>
<table style="background: #cccccc; margin-left: 1cm; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 426.1pt; padding-top: 0cm" valign="top" width="568">
            <p><em><span style="font-family: Arial">const char *pc = "a very long literal string";</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;<span style="color: red">const size_t len = strlen(pc +1);&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp;// space to</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;// performance test on string allocation and copy</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;for (size_t ix = 0; ix != 1; ++ix) {</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp; char *pc2 = new char[len + 1]; // allocate the space</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp; strcpy(pc2, pc);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // do the copy</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "pc2=" &lt;&lt; pc2 &lt;&lt; endl;</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "pc2[25]=" &lt;&lt; (pc2+25) &lt;&lt; endl;</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp; delete [] pc2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // free the memory</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;}</span></em></p>
            </td>
        </tr>
    </tbody>
</table>
<h2>4.4<span style="font-family: 黑体">多维数组</span> Multidimensioned Arrays</h2>
<p style="margin-left: 44.95pt; text-indent: -44.95pt"><span style="font-family: Arial">C++</span><span style="font-family: 宋体">实际是没有多维数组的，</span></p>
<p style="margin-left: 44.95pt; text-indent: -44.95pt"><em><span style="font-family: Arial">int ia[3][4]</span></em></p>
<p><span style="font-family: 宋体">可以理解为数字大小是</span><span style="font-family: Arial">3</span><span style="font-family: 宋体">，每个单元</span><span style="font-family: Arial">element</span><span style="font-family: 宋体">又是一个大小是</span><span style="font-family: Arial">4</span><span style="font-family: 宋体">的</span><span style="font-family: Arial">int</span><span style="font-family: 宋体">数组。或者叫做</span><span style="font-family: Arial">3</span><span style="font-family: 宋体">行</span><span style="font-family: Arial">3</span><span style="font-family: 宋体">列。</span></p>
<h4>1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">指针和多维数组</span></h4>
<p><strong><span style="font-family: 宋体">这段代码就如同&#8220;回&#8221;字的</span></strong><strong><span style="font-family: Arial">N</span></strong><strong><span style="font-family: 宋体">多种写法一样：</span></strong></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int ia[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<span style="color: green">*ip</span></span><span style="color: green; font-family: 宋体">是一个指针变量，它指向的是长度是</span><span style="color: green; font-family: Arial">4</span><span style="color: green; font-family: 宋体">的</span><span style="color: green; font-family: Arial">int</span><span style="color: green; font-family: 宋体">数组。</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*ip)[4]=ia;</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<span style="color: green">*ipo</span></span><span style="color: green; font-family: 宋体">是一个指针数组</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int *ipo[4] ;</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ipo[2]=ia[2]; //</span><span style="color: green; font-family: 宋体">对指针数组的单元赋值</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<span style="color: green">*ipt</span></span><span style="color: green; font-family: 宋体">就是一个最普通的指针，对指针变量赋值</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int *ipt=ia[2];</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int (*ipn)[4]=ia;</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ipn=&amp;ia[2]; //</span><span style="color: green; font-family: 宋体">也可以写为</span><span style="color: green; font-family: Arial">ia+2</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "(*(ip+2))[0]=" &lt;&lt; (*(ip+2))[0] &lt;&lt; endl;</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "ipo[2][0]=" &lt;&lt; ipo[2][0] &lt;&lt; endl;</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "ipt[0]=" &lt;&lt; ipt[0] &lt;&lt; endl;</span></p>
            <p><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "(*ipn)[0]=" &lt;&lt; (*ipn)[0] &lt;&lt; endl;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">打印结果是一样的，都是&#8216;</span><span style="font-family: Arial">8</span><span style="font-family: 宋体">&#8217;。</span></p>
<h4>2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">以下</span>2<span style="font-family: 宋体">种定义的区别（圆括号是必不可少的）</span></h4>
<p><span style="font-family: 宋体">指针数组：</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">&nbsp;int *ip[4]; // array of pointers to int</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">如果从内向外阅读</span><span style="font-family: Arial"> ip </span><span style="font-family: 宋体">的声明，则可理解为：</span><span style="font-family: Arial">*ip </span><span style="font-family: 宋体">是</span><span style="font-family: Arial"> int[4] </span><span style="font-family: 宋体">类型——即</span><span style="font-family: Arial"> ip </span><span style="font-family: 宋体">是一个指向含有</span><span style="font-family: Arial"> 4 </span><span style="font-family: 宋体">个元素的数组的指针。</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">&nbsp;int (*ip)[4]; // pointer to an array of 4 ints </span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong><span style="font-family: 宋体">进一步的理解：</span></strong></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">int (*ip)[4]=ia;</span></p>
            <p><span style="font-family: Arial">ip=&amp;ia[2]; //</span><span style="color: green; font-family: 宋体">也可以写为</span><span style="color: green; font-family: Arial">ia+2</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">刚开始，我觉得应该写成</span><em><span style="font-family: Arial">ip=ia[2];</span></em><span style="font-family: 宋体">结果得到报错信息：</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p style="margin-left: 17.95pt"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">error: cannot convert `int[4]' to `int (*)[4]' in assignment</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">因为</span><span style="font-family: Arial">ia[2]</span><span style="font-family: 宋体">就是一个数组啊，再想如果这样写</span><em><span style="font-family: Arial">ip=ia[2];</span></em><span style="font-family: 宋体">这就相当于</span></p>
<table style="margin-left: 23.4pt; border-collapse: collapse" cellspacing="0" cellpadding="0" border="0">
    <tbody>
        <tr>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 396pt; padding-top: 0cm" valign="top" width="528">
            <p><span style="font-family: Arial">int ia[4]= {0,1,2,3};</span></p>
            <p><span style="font-family: Arial">int *ip=ia;</span></p>
            <p><span style="font-family: Arial">ip=ia[2]; </span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 17.95pt"><span style="font-family: 宋体">当然是错误的。</span></p>
 <img src ="http://www.blogjava.net/amenglai/aggbug/269168.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> 2009-05-06 09:59 <a href="http://www.blogjava.net/amenglai/articles/269168.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++Primer 读书笔记 第三章</title><link>http://www.blogjava.net/amenglai/articles/267940.html</link><dc:creator>amenglai</dc:creator><author>amenglai</author><pubDate>Tue, 28 Apr 2009 08:25:00 GMT</pubDate><guid>http://www.blogjava.net/amenglai/articles/267940.html</guid><wfw:comment>http://www.blogjava.net/amenglai/comments/267940.html</wfw:comment><comments>http://www.blogjava.net/amenglai/articles/267940.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/amenglai/comments/commentRss/267940.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/amenglai/services/trackbacks/267940.html</trackback:ping><description><![CDATA[&nbsp;
<p style="text-align: center" align="center"><strong><span style="font-size: 15pt; font-family: 宋体">第三章</span></strong><strong><span style="font-size: 15pt; font-family: 宋体">标准库类型</span></strong></p>
<p style="text-align: center" align="center"><strong><span style="font-size: 15pt; font-family: Arial">Library Types</span></strong></p>
<h2>3.1 Namespace</h2>
<p><span style="font-family: 宋体">为什么要用</span><span style="font-family: Arial">namespace</span><span style="font-family: 宋体">？</span></p>
<p><span style="font-family: Arial">namespace</span><span style="font-family: 宋体">就是为了区分重名的类。</span></p>
<p><span style="font-family: 宋体">名字空间的主要作用是解决标识符冲突问题。</span>&nbsp;<span style="font-family: Arial"> <br />
</span>&nbsp;<span style="font-family: 宋体">比如</span><span style="font-family: Arial">C++ </span>&nbsp;<span style="font-family: Arial"> Standard </span>&nbsp;<span style="font-family: Arial"> Library</span><span style="font-family: 宋体">就是在名字空间</span><span style="font-family: Arial">std</span><span style="font-family: 宋体">下，如果没有名字空间，其中的</span><span style="font-family: Arial">list</span><span style="font-family: 宋体">就非常可能和自己定义的一些标识符重复。</span>&nbsp;<span style="font-family: Arial"> <br />
</span>&nbsp;<span style="font-family: 宋体">两种使用方法：</span>&nbsp;<span style="font-family: Arial"> <br />
</span>&nbsp;<span style="font-family: Arial"> 1</span><span style="font-family: 宋体">、</span>&nbsp;<span style="font-family: Arial"> std::list&lt;int&gt; </span>&nbsp;<span style="font-family: Arial"> myIntList; </span>&nbsp;<span style="font-family: Arial"> <br />
</span>&nbsp;<span style="font-family: Arial"> 2</span><span style="font-family: 宋体">、在</span><span style="font-family: Arial">cpp</span><span style="font-family: 宋体">文件的开头加上</span><span style="font-family: Arial">using </span>&nbsp;<span style="font-family: Arial"> namespace </span>&nbsp;<span style="font-family: Arial"> std; </span>&nbsp;<span style="font-family: Arial"> <br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-family: 宋体">这样在文件中就可以直接使用</span><span style="font-family: Arial">list&lt;int&gt; </span>&nbsp;<span style="font-family: Arial"> myIntList</span><span style="font-family: 宋体">了。</span></p>
<h2>3.2 string</h2>
<p><span style="font-family: 宋体">初始化：</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p><em><span style="font-family: Arial">string s1;</span></em></p>
            <p><em><span style="font-family: Arial">string s2(s1);</span></em></p>
            <p><em><span style="font-family: Arial">string s3("value");</span></em></p>
            <p><em><span style="font-family: Arial">string s4(n, 'c');</span></em></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">读入</span><span style="font-family: Arial">string</span><span style="font-family: 宋体">对象，有两种方式</span></p>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">使用读入操作符</span><em><span style="font-family: Arial">cin</span></em></p>
<table style="border-right: medium none; border-top: medium none; margin-left: 32.4pt; border-left: medium none; width: 360pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 360pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="480">
            <p style="margin-left: 3.55pt; text-indent: 0.05pt"><span style="font-family: Arial">cin &gt;&gt; s1 &gt;&gt; s2;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21pt; text-indent: -21pt; tab-stops: list 21.0pt"><span style="font-family: Arial">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">使用</span><em><span style="font-family: Arial">getline()</span></em><span style="font-family: 宋体">函数</span></p>
<table style="border-right: medium none; border-top: medium none; margin-left: 32.4pt; border-left: medium none; width: 360pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="480" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 360pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="480">
            <p><span style="font-family: Arial">getline(cin, line)</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">输入操作符会忽略开头的空格，直至遇到第一个空白字符（</span><span style="font-family: Arial">leading space</span><span style="font-family: 宋体">）就停止读入。和输入操作符不一样的是，</span><tt><span style="font-family: Arial">getline() </span></tt><span style="font-family: 宋体">并不忽略行开头的换行符。</span></p>
<p><em><span style="font-family: Arial">String.size()</span></em><span style="font-family: 宋体">返回的不是</span><span style="font-family: Arial">int</span><span style="font-family: 宋体">或者</span><span style="font-family: Arial">unsigned</span><span style="font-family: 宋体">数据类型，而是一个和机器无关的</span><strong><em><span style="font-family: Arial">string::size_type</span></em></strong><span style="font-family: 宋体">，虽然不知道</span><span style="font-family: Arial">string::size_type</span><span style="font-family: 宋体">的具体类型，但可以肯定的是它一定是</span><span style="font-family: Arial">unsigned</span><span style="font-family: 宋体">类型。</span></p>
<table style="border-right: medium none; border-top: medium none; margin-left: 23.4pt; border-left: medium none; width: 333pt; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" width="444" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 333pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="444">
            <p><span style="font-family: Arial">string st1, st2 = "The expense of spirit";</span></p>
            <p><span style="font-family: Arial">st1 = st2; // </span><span style="font-family: 宋体">这是两个对象，</span><span style="font-family: Arial">replace</span><span style="font-family: Arial"> st1 by a copy of st2</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">更加关键的是</span><em><span style="font-family: Arial">st1 = st2;</span></em><span style="font-family: 宋体">的执行过程：</span></p>
<p><span style="font-family: Arial">1</span><span style="font-family: 宋体">实际上是把原来分配给</span><span style="font-family: Arial">st1</span><span style="font-family: 宋体">的空间删除掉，</span></p>
<p><span style="font-family: Arial">2</span><span style="font-family: 宋体">再分配新的空间，</span><span style="font-family: Arial">copy</span><span style="font-family: 宋体">过来</span><span style="font-family: Arial">st2</span><span style="font-family: 宋体">的内容。</span></p>
<h2>3.3 vector</h2>
<p><span style="font-family: Arial">vector</span><span style="font-family: 宋体">中包含的必须是统一的数据类型。</span></p>
<p><span style="font-family: Arial">vector</span><span style="font-family: 宋体">不是一种类型，这是一个模板</span><span style="font-family: Arial">template</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: Arial">vector</span><span style="font-family: 宋体">并不需要预先分配内存空间。</span></p>
<p><span style="font-family: 宋体">初始化：</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p><span style="font-family: Arial">vector&lt;T&gt; v1;</span></p>
            <p><span style="font-family: Arial">vector&lt;T&gt; v2(v1);</span></p>
            <p><span style="font-family: Arial">vector&lt;T&gt; v3(n, i);</span></p>
            <p><span style="font-family: Arial">vector&lt;T&gt; v4(n);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: Arial">vector</span><span style="font-family: 宋体">的大小</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p style="text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; vector&lt;</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">int</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&gt; ivec(10,1);</span></p>
            <p><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; vector&lt;</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">int</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&gt;::size_type size = ivec.size();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: Arial">tip</span><span style="font-family: 宋体">：</span></p>
<p><span style="font-family: 宋体">如果要取得</span><span style="font-family: Arial">vector</span><span style="font-family: 宋体">的大小，要定义数据类型是</span><em><span style="font-family: Arial">vector&lt;int&gt;::size_type</span></em><span style="font-family: 宋体">。这和</span><span style="font-family: Arial">Java</span><span style="font-family: 宋体">有很大的不同，随意性很小了。</span></p>
<h2>3.4 Introducing Iterators</h2>
<p><span style="font-family: 宋体">每个容器类型都会定义自己的迭代类型。</span></p>
<p style="margin-left: 27pt"><span style="font-family: Arial">vector&lt;int&gt;</span><span style="font-family: 宋体">对应的迭代类型就是</span><strong><em><span style="font-family: Arial">vector&lt;int&gt;::iterator</span></em></strong><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">每个容器类型中都会包含一个成员（</span><span style="font-family: Arial">member</span><span style="font-family: 宋体">），这个成员是容器的迭代器的实际类型。</span></p>
<p><span style="font-family: 宋体">只要一种类型实现了迭代器所定义的所有操作，那么这种类型就可以称为是一个迭代器类型（</span><span style="font-family: Arial">iterator type</span><span style="font-family: 宋体">）。因此迭代器类型有很多种。</span></p>
<p><span style="font-family: 宋体">每种容器类型都定义了对应的</span><span style="font-family: Arial">iterator</span><span style="font-family: 宋体">类型，但是并不是所有的容器类型都定义下表索引的方式。因此应使用容器访问容器的单元。</span></p>
<p><span style="font-family: 宋体">访问当前单元的值要使用解引用操作符</span><span style="font-family: Arial">*</span><span style="font-family: 宋体">，解引用操作符返回的是一个值。</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p><em><span style="font-family: Arial">for (vector&lt;int&gt;::iterator iter = ivec.begin();</span></em></p>
            <p><em><span style="font-family: Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iter != ivec.end(); ++iter)</span></em></p>
            <p style="text-indent: 10.5pt"><em><span style="font-family: Arial">*iter = 0; //set element to which iter refers to 0</span></em></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong><span style="font-family: Arial">const_iterator</span></strong></p>
<p><span style="font-family: 宋体">我刚开始不是很明白为什么要定义</span><span style="font-family: Arial">const_iterator</span><span style="font-family: 宋体">类型，后来看了下面的代码</span><span style="font-family: Arial"> &#8211; </span><span style="font-family: 宋体">以只读模式遍历一个</span><span style="font-family: Arial">vector</span><span style="font-family: 宋体">，就明白了</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p><span style="font-family: 宋体">定义：</span><span style="font-family: Arial">const vector&lt;int&gt;::iterator it</span></p>
            <p><span style="font-family: 宋体">遍历：</span><span style="font-family: Arial">++it</span><span style="font-family: 宋体">；</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">遍历：</span><span style="font-family: Arial">++it&nbsp;//</span><span style="font-family: 宋体">错误！</span></p>
<p><span style="font-family: 宋体">所以要这样定义：</span></p>
<p><span style="font-family: Arial">vector&lt;int&gt;::const_iterator it</span></p>
<p><span style="font-family: 宋体">遍历：</span><span style="font-family: Arial">++it&nbsp;// </span><span style="font-family: 'Comic Sans MS'">ok</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p><span style="font-family: Arial">// an iterator that cannot write elements</span></p>
            <p><span style="font-family: Arial">vector&lt;int&gt;::const_iterator</span></p>
            <p><span style="font-family: Arial">// an iterator whose value cannot change</span></p>
            <p><span style="font-family: Arial">const vector&lt;int&gt;::iterator</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">任何操作改变了</span><span style="font-family: Arial">vector</span><span style="font-family: 宋体">的</span><span style="font-family: Arial">size</span><span style="font-family: 宋体">，那么现有的</span><span style="font-family: Arial">iterator</span><span style="font-family: 宋体">都会失效。就是说，</span></p>
<p><span style="font-family: 宋体">先执行</span><em><span style="font-family: Arial">vector&lt;int&gt;::iterator iter = ivec.begin()</span></em></p>
<p><span style="font-family: 宋体">然后追加</span><span style="font-family: Arial">element</span><span style="font-family: 宋体">：</span><em><span style="font-family: Arial">ivec.add(9);</span></em></p>
<p><span style="font-family: 宋体">那么前面的</span><span style="font-family: Arial">iter</span><span style="font-family: 宋体">就失效了。</span></p>
<h2>3.5 bitset</h2>
<p><span style="font-family: 宋体">首先明确这和</span><span style="font-family: Arial">vector</span><span style="font-family: 宋体">一样，都是模板</span><span style="font-family: Arial">template</span><span style="font-family: 宋体">。</span><span style="font-family: Arial">bitset</span><span style="font-family: 宋体">只有大小的不同。</span></p>
<p><em><span style="font-family: Arial">bitset&lt;32&gt; bitvec; // 32 bits, all zero</span></em></p>
<p><span style="font-family: Arial">bitset</span><span style="font-family: 宋体">初始化</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p><span style="font-family: Arial">bitset&lt;n&gt; b;</span></p>
            <p><span style="font-family: Arial">bitset&lt;n&gt; b(u);</span></p>
            <p><span style="font-family: Arial">bitset&lt;n&gt; b(s);</span></p>
            <p><span style="font-family: Arial">bitset&lt;n&gt; b(s, pos, n); //b </span><span style="font-family: 宋体">是</span><span style="font-family: Arial"> string </span><span style="font-family: 宋体">对象</span><span style="font-family: Arial"> s</span><span style="font-family: 宋体">中含有的位串的副本，从</span><span style="font-family: Arial">pos</span><span style="font-family: 宋体">位置截取</span><span style="font-family: Arial">n</span><span style="font-family: 宋体">个</span><span style="font-family: Arial">bit</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">从构造函数可以看出，</span><span style="font-family: Arial">bitset</span><span style="font-family: 宋体">是指定长度的，这和</span><span style="font-family: Arial">vector</span><span style="font-family: 宋体">有点不一样。</span></p>
<p><span style="font-family: 宋体">从</span><span style="font-family: Arial">string</span><span style="font-family: 宋体">初始化</span><span style="font-family: Arial">bitset</span><span style="font-family: 宋体">，要注意的是</span><span style="font-family: Arial">string</span><span style="font-family: 宋体">和</span><span style="font-family: Arial">bitset</span><span style="font-family: 宋体">的顺序是相反的：就是说从右向左读</span><span style="font-family: Arial">string</span><span style="font-family: 宋体">的</span><span style="font-family: Arial">bit</span><span style="font-family: 宋体">。</span></p>
<p><span style="font-family: 宋体">例如：</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 293.4pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="391">
            <p><em><span style="font-family: Arial">string strval("1100");</span></em></p>
            <p><em><span style="font-family: Arial">bitset&lt;32&gt; bitvec4(strval);</span></em></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体">那么</span><span style="font-family: Arial">bitvec4</span><span style="font-family: 宋体">的第</span><span style="font-family: Arial">2</span><span style="font-family: 宋体">位，第</span><span style="font-family: Arial">3</span><span style="font-family: 宋体">位才是</span><span style="font-family: Arial">1.</span><span style="font-family: 宋体">即使是对</span><span style="font-family: Arial">string</span><span style="font-family: 宋体">的截串处理也应保证<strong>从右向左读</strong>。</span></p>
<img src ="http://www.blogjava.net/amenglai/aggbug/267940.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> 2009-04-28 16:25 <a href="http://www.blogjava.net/amenglai/articles/267940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>