﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-CPP Blog-随笔分类-C++</title><link>http://www.cppblog.com/samofweb/category/12752.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 18 Feb 2010 14:45:41 GMT</lastBuildDate><pubDate>Thu, 18 Feb 2010 14:45:41 GMT</pubDate><ttl>60</ttl><item><title>How to delete element from Vector </title><link>http://www.cppblog.com/samofweb/archive/2010/02/18/107995.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Wed, 17 Feb 2010 22:02:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/02/18/107995.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/107995.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/02/18/107995.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/107995.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/107995.html</trackback:ping><description><![CDATA[How to delete element from Vector:<br><br>There is tricky thing for deleting in vector loop.<br><br>The erase method returns the next element after the one you just erased.  So you can use that to continue in your loop.<br>
<br>
vector c;<br>
iterator i = c.begin();<br>&nbsp;&nbsp;&nbsp;&nbsp;
while(i != c.end()){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i == something) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //i = i.erase();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = c.erase(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; i++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
}<br><br>OR:<br><br>vector c;<br>for(vector&lt;type&gt;::iterator i=c.begin(); i != c.end(); )<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp; if (some condition)<br>&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //i = i.erase();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = c.erase(i);<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp; else <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++i;<br>}<br><br><br><br><br> <img src ="http://www.cppblog.com/samofweb/aggbug/107995.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-02-18 06:02 <a href="http://www.cppblog.com/samofweb/archive/2010/02/18/107995.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用标准C++的类型转换符：static_cast、dynamic_cast、reinterpret_cast、和const_cast</title><link>http://www.cppblog.com/samofweb/archive/2010/02/11/107689.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Thu, 11 Feb 2010 01:04:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/02/11/107689.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/107689.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/02/11/107689.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/107689.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/107689.html</trackback:ping><description><![CDATA[总结C++中的所有强制转换函数(const_cast，reinterpret_cast，static_cast，dynamic_cast) <br><br>C&nbsp;风格（C-style）强制转型如下： <br><br>(T)&nbsp;expression&nbsp;//&nbsp;cast&nbsp;expression&nbsp;to&nbsp;be&nbsp;of&nbsp;type&nbsp;T <br><br>函数风格（Function-style）强制转型使用这样的语法： <br><br>T(expression)&nbsp;//&nbsp;cast&nbsp;expression&nbsp;to&nbsp;be&nbsp;of&nbsp;type&nbsp;T <br><br>这两种形式之间没有本质上的不同，它纯粹就是一个把括号放在哪的问题。我把这两种形式称为旧风格（old-style）的强制转型。 <br><br>使用标准C++的类型转换符：static_cast、dynamic_cast、reinterpret_cast、和const_cast。 <br><br>3.1&nbsp;static_cast <br>用法：static_cast&nbsp; &lt;&nbsp;type-id&nbsp;&gt; &nbsp;(&nbsp;expression&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>该运算符把expression转换为type-id类型，但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法： <br>①用于类层次结构中基类和子类之间指针或引用的转换。 <br>进行上行转换（把子类的指针或引用转换成基类表示）是安全的； <br>进行下行转换（把基类指针或引用转换成子类表示）时，由于没有动态类型检查，所以是不安全的。 <br>②用于基本数据类型之间的转换，如把int转换成char，把int转换成enum。这种转换的安全性也要开发人员来保证。 <br>③把空指针转换成目标类型的空指针。 <br>④把任何类型的表达式转换成void类型。 <br><br>注意：static_cast不能转换掉expression的const、volitale、或者__unaligned属性。 <br><br><br>3.2&nbsp;dynamic_cast <br>用法：dynamic_cast&nbsp; &lt;&nbsp;type-id&nbsp;&gt; &nbsp;(&nbsp;expression&nbsp;) <br>该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void&nbsp;*； <br>如果type-id是类指针类型，那么expression也必须是一个指针，如果type-id是一个引用，那么expression也必须是一个引用。 <br><br>dynamic_cast主要用于类层次间的上行转换和下行转换，还可以用于类之间的交叉转换。 <br>在类层次间进行上行转换时，dynamic_cast和static_cast的效果是一样的； <br>在进行下行转换时，dynamic_cast具有类型检查的功能，比static_cast更安全。 <br>class&nbsp;B{ <br>public: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m_iNum; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;foo(); <br>}; <br><br>class&nbsp;D:public&nbsp;B{ <br>&nbsp;&nbsp;&nbsp;&nbsp;public: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;*m_szName[100]; <br>}; <br><br>void&nbsp;func(B&nbsp;*pb){ <br>&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;*pd1&nbsp;=&nbsp;static_cast &lt;D&nbsp;*&gt; (pb); <br>&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;*pd2&nbsp;=&nbsp;dynamic_cast &lt;D&nbsp;*&gt; (pb); <br>} <br><br>在上面的代码段中，如果pb指向一个D类型的对象，pd1和pd2是一样的，并且对这两个指针执行D类型的任何操作都是安全的； <br>但是，如果pb指向的是一个B类型的对象，那么pd1将是一个指向该对象的指针，对它进行D类型的操作将是不安全的（如访问m_szName）， <br>而pd2将是一个空指针。 <br><br>另外要注意：B要有虚函数，否则会编译出错；static_cast则没有这个限制。 <br>这是由于运行时类型检查需要运行时类型信息，而这个信息存储在类的虚函数表（ <br>关于虚函数表的概念，详细可见 &lt;Inside&nbsp;c++&nbsp;object&nbsp;model&gt; ）中，只有定义了虚函数的类才有虚函数表， <br>没有定义虚函数的类是没有虚函数表的。 <br><br>另外，dynamic_cast还支持交叉转换（cross&nbsp;cast）。如下代码所示。 <br>class&nbsp;A{ <br>public: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m_iNum; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;f(){} <br>}; <br><br>class&nbsp;B:public&nbsp;A{ <br>}; <br><br>class&nbsp;D:public&nbsp;A{ <br>}; <br><br>void&nbsp;foo(){ <br>&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;*pb&nbsp;=&nbsp;new&nbsp;B; <br>&nbsp;&nbsp;&nbsp;&nbsp;pb-&gt; m_iNum&nbsp;=&nbsp;100; <br><br>&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;*pd1&nbsp;=&nbsp;static_cast &lt;D&nbsp;*&gt; (pb);&nbsp;&nbsp;&nbsp;&nbsp;//compile&nbsp;error <br>&nbsp;&nbsp;&nbsp;&nbsp;D&nbsp;*pd2&nbsp;=&nbsp;dynamic_cast &lt;D&nbsp;*&gt; (pb);&nbsp;//pd2&nbsp;is&nbsp;NULL <br>&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pb; <br>} <br><br>在函数foo中，使用static_cast进行转换是不被允许的，将在编译时出错；而使用&nbsp;dynamic_cast的转换则是允许的，结果是空指针。 <br><br><br>3.3&nbsp;reinpreter_cast <br>用法：reinpreter_cast &lt;type-id&gt; &nbsp;(expression) <br>type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。 <br>它可以把一个指针转换成一个整数，也可以把一个整数转换成一个指针（先把一个指针转换成一个整数， <br>在把该整数转换成原类型的指针，还可以得到原先的指针值）。 <br><br>该运算符的用法比较多。 <br><br>3.4&nbsp;const_cast <br>用法：const_cast &lt;type_id&gt; &nbsp;(expression) <br>该运算符用来修改类型的const或volatile属性。除了const&nbsp;或volatile修饰之外，&nbsp;type_id和expression的类型是一样的。 <br>常量指针被转化成非常量指针，并且仍然指向原来的对象； <br>常量引用被转换成非常量引用，并且仍然指向原来的对象；常量对象被转换成非常量对象。 <br><br>Voiatile和const类试。举如下一例： <br>class&nbsp;B{ <br>public: <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;m_iNum; <br>} <br>void&nbsp;foo(){ <br>const&nbsp;B&nbsp;b1; <br>b1.m_iNum&nbsp;=&nbsp;100;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//comile&nbsp;error <br>B&nbsp;b2&nbsp;=&nbsp;const_cast &lt;B&gt; (b1); <br>b2.&nbsp;m_iNum&nbsp;=&nbsp;200;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//fine <br>} <br>上面的代码编译时会报错，因为b1是一个常量对象，不能对它进行改变； <br>使用const_cast把它转换成一个常量对象，就可以对它的数据成员任意改变。注意：b1和b2是两个不同的对象。 <br><br>==&nbsp;=========================================== <br><br>==&nbsp;dynamic_cast&nbsp;.vs.&nbsp;static_cast <br>==&nbsp;=========================================== <br><br>class&nbsp;B&nbsp;{&nbsp;...&nbsp;}; <br>class&nbsp;D&nbsp;:&nbsp;public&nbsp;B&nbsp;{&nbsp;...&nbsp;}; <br><br>void&nbsp;f(B*&nbsp;pb) <br>{ <br><br>D*&nbsp;pd1&nbsp;=&nbsp;dynamic_cast &lt;D*&gt; (pb); <br><br>D*&nbsp;pd2&nbsp;=&nbsp;static_cast &lt;D*&gt; (pb); <br>} <br><br>If&nbsp;pb&nbsp;really&nbsp;points&nbsp;to&nbsp;an&nbsp;object&nbsp;of&nbsp;type&nbsp;D,&nbsp;then&nbsp;pd1&nbsp;and&nbsp;pd2&nbsp;will&nbsp;get&nbsp;the&nbsp;same&nbsp;value.&nbsp;They&nbsp;will&nbsp;also&nbsp;get&nbsp;the&nbsp;same&nbsp;value&nbsp;if&nbsp;pb&nbsp;==&nbsp;0.
<br><br>If&nbsp;pb&nbsp;points&nbsp;to&nbsp;an&nbsp;object&nbsp;of&nbsp;type&nbsp;B&nbsp;and&nbsp;not&nbsp;to&nbsp;the&nbsp;complete&nbsp;D&nbsp;class,&nbsp;then&nbsp;dynamic_cast&nbsp;will&nbsp;know&nbsp;enough&nbsp;to&nbsp;return&nbsp;zero.&nbsp;However,&nbsp;static_cast&nbsp;relies&nbsp;on&nbsp;the&nbsp;programmer&#8217;s&nbsp;assertion&nbsp;that&nbsp;pb&nbsp;points&nbsp;to&nbsp;an&nbsp;object&nbsp;of&nbsp;type&nbsp;D&nbsp;and&nbsp;simply&nbsp;returns&nbsp;a&nbsp;pointer&nbsp;to&nbsp;that&nbsp;supposed&nbsp;D&nbsp;object.
<br><br>即dynamic_cast可用于继承体系中的向下转型，即将基类指针转换为派生类指针，比static_cast更严格更安全。
dynamic_cast在执行效率上比static_cast要差一些，但static_cast在更宽上范围内可以完成映射，这种不加限制的映射伴随
着不安全性。static_cast覆盖的变换类型除类层次的静态导航以外，还包括无映射变换、窄化变换(这种变换会导致对象切片,丢失信息)、用
VOID*的强制变换、隐式类型变换等... <br><br><br>==&nbsp;=========================================== <br>==&nbsp;static_cast&nbsp;.vs.&nbsp;reinterpret_cast <br>==&nbsp;================================================ <br><br>reinterpret_cast是为了映射到一个完全不同类型的意思，这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的，这是所有映射中最危险的。(这句话是C++编程思想中的原话) <br><br>static_cast&nbsp;和&nbsp;reinterpret_cast&nbsp;操
作符修改了操作数类型。它们不是互逆的；&nbsp;static_cast&nbsp;在编译时使用类型信息执行转换，在转换执行必要的检测(诸如指针越界计算,&nbsp;类型检
查).&nbsp;其操作数相对是安全的。另一方面；reinterpret_cast&nbsp;仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换，&nbsp;例子如下：
<br><br>int&nbsp;n=9;&nbsp;double&nbsp;d=static_cast&nbsp; &lt;&nbsp;double&nbsp;&gt; &nbsp;(n); <br><br>上面
的例子中,&nbsp;我们将一个变量从&nbsp;int&nbsp;转换到&nbsp;double。&nbsp;这些类型的二进制表达式是不同的。&nbsp;要将整数&nbsp;9&nbsp;转换到&nbsp;双精度整
数&nbsp;9，static_cast&nbsp;需要正确地为双精度整数&nbsp;d&nbsp;补足比特位。其结果为&nbsp;9.0。而reinterpret_cast&nbsp;的行为却不同: <br><br>int&nbsp;n=9; <br><br>double&nbsp;d=reinterpret_cast &lt;double&nbsp;&amp;&nbsp;&gt; &nbsp;(n); <br><br>这次,&nbsp;结果有所不同.&nbsp;在进行计算以后,&nbsp;d&nbsp;包含无用值.&nbsp;这是因为&nbsp;reinterpret_cast&nbsp;仅仅是复制&nbsp;n&nbsp;的比特位到&nbsp;d,&nbsp;没有进行必要的分析. <br><br>因此,&nbsp;你需要谨慎使用&nbsp;reinterpret_cast. <br># <br>#&nbsp;标准c++中主要有四种强制转换类型运算符：&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;const_cast，reinterpret_cast，static_cast，dynamic_cast等等。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;1）static_cast &lt;T*&gt; (a)&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;将地址a转换成类型T，T和a必须是指针、引用、算术类型或枚举类型。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;表达式static_cast &lt;T*&gt; (a),&nbsp;a的值转换为模板中指定的类型T。在运行时转换过程中，不进行类型检查来确保转换的安全性。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;例子：&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;class&nbsp;D&nbsp;:&nbsp;public&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;void&nbsp;f(B*&nbsp;pb,&nbsp;D*&nbsp;pd)&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;{&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D*&nbsp;pd2&nbsp;=&nbsp;static_cast &lt;D*&gt; (pb);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;不安全,&nbsp;pb可能只是B的指针&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B*&nbsp;pb2&nbsp;=&nbsp;static_cast &lt;B*&gt; (pd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;安全的&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;}&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br># <br><br>#&nbsp;2）dynamic_cast &lt;T*&gt; (a)&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;完成类层次结构中的提升。T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;表达式dynamic_cast &lt;T*&gt; (a)&nbsp;将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型，该操作将返回一个空指针。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;例子：&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;void&nbsp;f()&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;{&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;A*&nbsp;pa&nbsp;=&nbsp;new&nbsp;A;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;B*&nbsp;pb&nbsp;=&nbsp;new&nbsp;B;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;void*&nbsp;pv&nbsp;=&nbsp;dynamic_cast &lt;A*&gt; (pa);&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;//&nbsp;pv&nbsp;现在指向了一个类型为A的对象&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;pv&nbsp;=&nbsp;dynamic_cast &lt;B*&gt; (pb);&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;//&nbsp;pv&nbsp;现在指向了一个类型为B的对象&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;}&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;3）const_cast &lt;T*&gt; (a)&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;去掉类型中的常量，除了const或不稳定的变址数，T和a必须是相同的类型。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;表达式const_cast &lt;T*&gt; (a)被用于从一个类中去除以下这些属性：const,&nbsp;volatile,&nbsp;和&nbsp;__unaligned。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;例子：&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;void&nbsp;f()&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;{&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;const&nbsp;A&nbsp;*pa&nbsp;=&nbsp;new&nbsp;A;//const对象&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;A&nbsp;*pb;//非const对象&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;//pb&nbsp;=&nbsp;pa;&nbsp;//&nbsp;这里将出错，不能将const对象指针赋值给非const对象&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;pb&nbsp;=&nbsp;const_cast &lt;A*&gt; (pa);&nbsp;//&nbsp;现在OK了&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;...&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;}&nbsp;&nbsp; <br># <br><br>#&nbsp;4）reinterpret_cast &lt;T*&gt; (a)&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;任何指针都可以转换成其它类型的指针，T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;表达式reinterpret_cast &lt;T*&gt; (a)能够用于诸如char*&nbsp;到&nbsp;int*，或者One_class*&nbsp;到&nbsp;Unrelated_class*等类似这样的转换，因此可能是不安全的。&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;例子：&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;class&nbsp;A&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;class&nbsp;B&nbsp;{&nbsp;...&nbsp;};&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;void&nbsp;f()&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;{&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;A*&nbsp;pa&nbsp;=&nbsp;new&nbsp;A;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;void*&nbsp;pv&nbsp;=&nbsp;reinterpret_cast &lt;A*&gt; (pa);&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;//&nbsp;pv&nbsp;现在指向了一个类型为B的对象，这可能是不安全的&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp; <br>#&nbsp;&nbsp;&nbsp; <br>#&nbsp;}&nbsp;<img src ="http://www.cppblog.com/samofweb/aggbug/107689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-02-11 09:04 <a href="http://www.cppblog.com/samofweb/archive/2010/02/11/107689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>结合设计模式理解多用组合少用继承的原则（转）</title><link>http://www.cppblog.com/samofweb/archive/2010/02/11/107687.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Wed, 10 Feb 2010 23:25:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/02/11/107687.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/107687.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/02/11/107687.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/107687.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/107687.html</trackback:ping><description><![CDATA[刚刚接触模式或者学习模式的人，经常会有这样的问题，为什么模式是成功的呢？很多人都会说模式是经验的积累，当然是正确的。可是经验为什么偏偏就证明了这
种模式是正确的呢？这其中起用作的就是面向对象的基本原则。正是因为模式都或多或少的符合了面向对象的基本原则，所以模式才成为我们面向对象的设计和编码
过程中不败的法则。那么什么是面向对象的基本原则呢？这就是我们将要一一讲到的问题。
<br>单纯的讲到一个个的原则，就是那么的寥寥几句，非常的简单，但又是非常抽象的，难以理解。怎么办？
<br>任何的理论，只要有生动的例子来讲解或证明，就能极大的帮助理解。所以我们准备从一个个的生动的例子来阐述我们的面向对象的基本原则。讲那些例子呢？上面我们说到，模式都是极大的遵从了这些原则的，那么我们把模式作为例子，来说明这些原则，不是我们信手拈来的吗？
<br>现在我们说说其中的一个原则：对类的功能的扩展，要<strong>多用组合，少用继承</strong>。
<br>对于类的扩展，在面向对象的编程过程中，我们首先想到的是类的继承，由子类继承父类，从而完成了对子类功能的扩展。但是，面向对象的原则告诉我们，对类的功能的扩展要多用组合，而少用继承。其中的原因有以下几点：
<br>第一、子类对父类的继承是全部的公有和受保护的继承，这使得子类可能继承了对子类无用甚至有害的父类的方法。换句话说，子类只希望继承父类的一部分方法，怎么办？
<br>第二、实际的对象千变万化，如果每一类的对象都有他们自己的类，尽管这些类都继承了他们的父类，但有些时候还是会造成类的无限膨胀。
<br>第三、 继承的子类，实际上需要编译期确定下来，这满足不了需要在运行内才能确定对象的情况。而组合却可以比继承灵活得多，可以在运行期才决定某个对象。
<br>嗨！光说这么多一二三有什么用，我们就是想看看实际情况是不是像上面说的那样呢？还是来看看实际的例子吧！
<br>现在我们需要这样一个HashMap，它除了能按常规的Map那样取值，如get(Object obj)。还能按位取值，像ArrayList那样，按存入对象对的先后顺序取值。
<br>对于这样一个问题，我们首先想到的是做一个类，它继承了HashMap类，然后用一个ArrayList属性来保存存入的key，我们按key的位来取值，代码如下：
<br>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://crud0906.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20class%20ListMap%20extends%20HashMap%20%7B%0Aprivate%20List%20list%3B%0Apublic%20ListMap()%20%7B%0A%20%20%20%20%20%20%20%20%20super()%3B%0A%20%20%20%20%20%20%20%20%20%20this.list%20%3D%20new%20ArrayList()%3B%0A%7D%0Apublic%20Object%20put(Object%20key%2CObject%20value)%0A%7B%0A%20%20%20%20%20%20%20%20%20if(list.contains(key))%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20list.remove(key)%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20this.list.add(key)%3B%0A%20%20%20%20%20%20%20%20%20%20return%20super.put(key%2Cvalue)%3B%0A%7D%0Apublic%20Object%20getKey(int%20i)%0A%7B%0A%20%20%20%20%20%20%20%20%20%20return%20this.list.get(i)%3B%0A%7D%0Apublic%20Object%20getValue(int%20i)%0A%7B%0A%20%20%20%20%20%20%20%20%20%20return%20this.get(getKey(i))%3B%0A%7D%0Apublic%20int%20size()%0A%7B%0A%20%20%20%20%20%20%20%20%20%20return%20this.list.size()%3B%0A%7D%0A%7D%0A%E8%BF%99%E4%B8%AAListMap%E7%B1%BB%E5%AF%B9HashMap%E4%BD%9C%E4%BA%86%E4%B8%80%E5%AE%9A%E7%9A%84%E6%89%A9%E5%B1%95%EF%BC%8C%E5%BE%88%E7%AE%80%E5%8D%95%E5%B0%B1%E5%AE%9E%E7%8E%B0%E4%BA%86%E4%B8%8A%E9%9D%A2%E6%88%91%E4%BB%AC%E6%89%80%E8%A6%81%E6%B1%82%E7%9A%84%E5%8A%9F%E8%83%BD%E3%80%82%E7%84%B6%E5%90%8E%E6%88%91%E4%BB%AC%E5%AF%B9%E8%AF%A5%E7%B1%BB%E5%81%9A%E4%B8%80%E4%B8%8B%E6%B5%8B%E8%AF%95%EF%BC%9A%0AListMap%20map%20%3D%20new%20ListMap()%3B%0A%20%20%20%20%20%20%20%20%20map.put(%22a%22%2C%22111%22)%3B%0A%20%20%20%20%20%20%20%20%20map.put(%22v%22%2C%22190%22)%3B%0A%20%20%20%20%20%20%20%20%20map.put(%22d%22%2C%22132%22)%3B%0A%20%20%20%20%20%20%20%20%20%20for(int%20i%3D0%3Bi%3Cmap.size()%3Bi%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(map.getValue(i))%3B%0A%20%20%20%20%20%20%20%20%20%20%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ListMap&nbsp;</span><span class="keyword">extends</span><span>&nbsp;HashMap&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">private</span><span>&nbsp;List&nbsp;list;&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;ListMap()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">super</span><span>();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.list&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ArrayList();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Object&nbsp;put(Object&nbsp;key,Object&nbsp;value)&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(list.contains(key))&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.remove(key);&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.list.add(key);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">super</span><span>.put(key,value);&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Object&nbsp;getKey(</span><span class="keyword">int</span><span>&nbsp;i)&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.list.get(i);&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Object&nbsp;getValue(</span><span class="keyword">int</span><span>&nbsp;i)&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.get(getKey(i));&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;size()&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.list.size();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>这个ListMap类对HashMap作了一定的扩展，很简单就实现了上面我们所要求的功能。然后我们对该类做一下测试：&nbsp;&nbsp;</span></li>
    <li><span>ListMap&nbsp;map&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;ListMap();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put(<span class="string">"a"</span><span>,</span><span class="string">"111"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put(<span class="string">"v"</span><span>,</span><span class="string">"190"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put(<span class="string">"d"</span><span>,</span><span class="string">"132"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>(</span><span class="keyword">int</span><span>&nbsp;i=</span><span class="number">0</span><span>;i&lt;map.size();i++)&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(map.getValue(i));&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">public class ListMap extends HashMap {
private List list;
public ListMap() {
super();
this.list = new ArrayList();
}
public Object put(Object key,Object value)
{
if(list.contains(key))
{
list.remove(key);
}
this.list.add(key);
return super.put(key,value);
}
public Object getKey(int i)
{
return this.list.get(i);
}
public Object getValue(int i)
{
return this.get(getKey(i));
}
public int size()
{
return this.list.size();
}
}
这个ListMap类对HashMap作了一定的扩展，很简单就实现了上面我们所要求的功能。然后我们对该类做一下测试：
ListMap map = new ListMap();
map.put("a","111");
map.put("v","190");
map.put("d","132");
for(int i=0;i&lt;map.size();i++)
{
System.out.println(map.getValue(i));
}</pre>
测试结果为：
<br>111
<br>190
<br>132
<br>正是我们所需要看到的结果。如此说来，这个ListMap类就可以放心的使用了吗？有实现了这样功能的类，你的同事或朋友也可能把这个类拿来使用一下，他可能写出来如下的代码：
<br>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://crud0906.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=ListMap%20map%20%3D%20new%20ListMap()%3B%0A%20%20%20%20%20%20%20%20%20map.put(%22a%22%2C%22111%22)%3B%0A%20%20%20%20%20%20%20%20%20map.put(%22v%22%2C%22190%22)%3B%0A%20%20%20%20%20%20%20%20%20map.put(%22d%22%2C%22132%22)%3B%0A%20%20%20%20%20%20%20%20%20String%5B%5D%20list%20%3D%20(String%5B%5D)map.values().toArray(new%20String%5B0%5D)%3B%0A%20%20%20%20%20%20%20%20%20%20for(int%20i%3D0%3Bi%3Clist.length%3Bi%2B%2B)%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(list%5Bi%5D)%3B%0A%20%20%20%20%20%20%20%20%20%20%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span>ListMap&nbsp;map&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ListMap();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put(<span class="string">"a"</span><span>,</span><span class="string">"111"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put(<span class="string">"v"</span><span>,</span><span class="string">"190"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.put(<span class="string">"d"</span><span>,</span><span class="string">"132"</span><span>);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String[]&nbsp;list&nbsp;=&nbsp;(String[])map.values().toArray(<span class="keyword">new</span><span>&nbsp;String[</span><span class="number">0</span><span>]);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>(</span><span class="keyword">int</span><span>&nbsp;i=</span><span class="number">0</span><span>;i&lt;list.length;i++)&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(list[i]);&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">ListMap map = new ListMap();
map.put("a","111");
map.put("v","190");
map.put("d","132");
String[] list = (String[])map.values().toArray(new String[0]);
for(int i=0;i&lt;list.length;i++)
{
System.out.println(list[i]);
}</pre>
运行的结果如下：
<br>132
<br>111
<br>190
<br>哎哟，怎么回事啊？与上面的顺序不对了。你朋友过来找你，说你写的代码怎么不对啊？你很吃惊，说把代码给我看看。于是你看到了上面的代码。你大骂道，混蛋，怎么不是用我的getValue方法啊？你朋友搔搔头道，values方法不是一样的吗？你也没告诉我不能用啊？
<br>通过上面的例子，我们看到了继承的第一个危害：继承不分青红皂白的把父类的公有和受保护的方法统统继承下来。如果你的子类没有对一些方法重写，就
会对你的子类产生危害。上面的ListMap类，你没有重写继承自HashMap类的values方法，而该方法仍然是按HashMap的方式取值，没有
先后顺序。这时候，如果在ListMap类的对象里使用该方法取得的值，就没有实现我们上面的要求。
<br>接上面的那个例子，你听了朋友的抱怨，摇摇头，想想也是，不能怪他。你只得把values方法在ListMap类重写一遍，然后又嘀咕着，我是不是该把HashMap类的公有方法在ListMap类里全部重写？很多方法根本没有必要用到啊？&#8230;&#8230;
<br>对了，很多方法在ListMap里根本不必用到，但是你用继承的话，还不得不在ListMap里重写它们。如果用组合的话，就没有上面的烦恼了：
<br>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://crud0906.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20class%20MyListMap%20%7B%0Aprivate%20HashMap%20map%3B%0Aprivate%20List%20list%3B%0Apublic%20MyListMap()%0A%7B%0A%20%20%20%20%20%20%20%20%20this.map%20%3D%20new%20HashMap()%3B%0A%20%20%20%20%20%20%20%20%20%20this.list%20%3D%20new%20ArrayList()%3B%0A%7D%0Apublic%20Object%20put(Object%20key%2CObject%20value)%0A%7B%0A%20%20%20%20%20%20%20%20%20if(list.contains(key))%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20list.remove(key)%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20this.list.add(key)%3B%0A%20%20%20%20%20%20%20%20%20%20return%20this.map.put(key%2Cvalue)%3B%0A%7D%0Apublic%20Object%20getKey(int%20i)%0A%7B%0A%20%20%20%20%20%20%20%20%20%20return%20this.list.get(i)%3B%0A%7D%0Apublic%20Object%20getValue(int%20i)%0A%7B%0A%20%20%20%20%20%20%20%20%20%20return%20this.map.get(getKey(i))%3B%0A%7D%0Apublic%20int%20size()%0A%7B%0A%20%20%20%20%20%20%20%20%20%20return%20this.list.size()%3B%0A%7D%0A%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;MyListMap&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">private</span><span>&nbsp;HashMap&nbsp;map;&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">private</span><span>&nbsp;List&nbsp;list;&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;MyListMap()&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.map&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;HashMap();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.list&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ArrayList();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Object&nbsp;put(Object&nbsp;key,Object&nbsp;value)&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(list.contains(key))&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.remove(key);&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.list.add(key);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.map.put(key,value);&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Object&nbsp;getKey(</span><span class="keyword">int</span><span>&nbsp;i)&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.list.get(i);&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Object&nbsp;getValue(</span><span class="keyword">int</span><span>&nbsp;i)&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.map.get(getKey(i));&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;size()&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">this</span><span>.list.size();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">public class MyListMap {
private HashMap map;
private List list;
public MyListMap()
{
this.map = new HashMap();
this.list = new ArrayList();
}
public Object put(Object key,Object value)
{
if(list.contains(key))
{
list.remove(key);
}
this.list.add(key);
return this.map.put(key,value);
}
public Object getKey(int i)
{
return this.list.get(i);
}
public Object getValue(int i)
{
return this.map.get(getKey(i));
}
public int size()
{
return this.list.size();
}
}</pre>
这样，你的朋友就只能使用你的getKey和getValue方法了。如果他向你抱怨没有values方法，你尽可以满足他的要求，给他添加上那个方法，而不必担心可能还有方法没有被重写了。
<br>我们来看Adapter模式，该模式的目的十分简单：我手里握有一些实现了WhatIHave接口的实现，可我觉得这些实现的功能不够用，我还需要从Resource类里取一些功能来为我所用。Adapter模式的解决方法如下：
<br>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://crud0906.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20interface%20WhatIHave%0A%7B%0A%20%20%20%20%20%20%20%20%20%20public%20void%20g()%3B%0A%7D%0Apublic%20class%20Resource%0A%7B%0A%20%20%20%20%20%20%20%20%20%20public%20void%20f()%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%80%A6%E2%80%A6%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20public%20void%20h()%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%80%A6%E2%80%A6%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;WhatIHave&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;g();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Resource&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;f()&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;h()&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">public interface WhatIHave
{
public void g();
}
public class Resource
{
public void f()
{
&#8230;&#8230;
}
public void h()
{
&#8230;&#8230;
}
}</pre>
上面是两个基础类，很明显，我们所要的类既要有g()方法，也要有f()和h()方法。
<br>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://crud0906.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=Public%20class%20WhatIWant%20implements%20WhatIHave%0A%7B%0A%20%20%20%20%20%20%20%20%20%20private%20Resource%20res%3B%0A%20%20%20%20%20%20%20%20%20%20public%20WhatIWant()%0A%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20res%20%3D%20new%20Resource()%3B%0A%7D%0Apublic%20void%20g()%0A%7B%0A%20%20%20%20%20%20%20%E2%80%A6%E2%80%A6%0A%7D%0Apublic%20void%20f()%0A%7B%0A%20%20%20%20%20%20%20%20%20this.res.f()%3B%0A%7D%0Apublic%20void%20h()%0A%7B%0A%20%20%20%20%20%20%20%20%20this.res.h()%3B%0A%7D%0A%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span>Public&nbsp;</span><span class="keyword">class</span><span>&nbsp;WhatIWant&nbsp;</span><span class="keyword">implements</span><span>&nbsp;WhatIHave&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;Resource&nbsp;res;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;WhatIWant()&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Resource();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;g()&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;f()&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.res.f();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;h()&nbsp;&nbsp;</span></span></li>
    <li><span>{&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.res.h();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">Public class WhatIWant implements WhatIHave
{
private Resource res;
public WhatIWant()
{
res = new Resource();
}
public void g()
{
&#8230;&#8230;
}
public void f()
{
this.res.f();
}
public void h()
{
this.res.h();
}
}</pre>
上
面就是一个Adapter模式最简单的解决问题的思路。我们主要到，对于Resource类，该模式使用的是组合，而不是继承。这样使用是有多个原因：第
一，Java不支持多重继承，如果需要使用好几个不同的Resource类，则继承解决不了问题。第二，如果Resource类还有一个方法：k()，我
们在WhatIWant类里使用不上的话，继承就给我们造成多余方法的问题了。
<br>如果说Adapter模式对组合的应用的目的十分简单明确，那么Decorator模式对组合的应用简直就是令人叫绝。
<br>让我们还是从Decorator模式的最佳例子说起，咖啡店需要售卖各种各样的咖啡：黑咖啡、加糖、加冰、加奶、加巧克力等等。顾客要买咖啡，他可以往咖啡任意的一种或几种产品。
<br>这个问题一提出来，我们最容易想到的是继承。比如说加糖咖啡是一种咖啡，满足ia
a的句式，很明显，加糖咖啡是咖啡的一个子类。于是，我们马上可以赋之行动。对于咖啡我们做一个咖啡类：Coffee，咖啡加
糖：SugarCoffee，咖啡加冰：IceCoffee，咖啡加奶：MilkCoffee，咖啡加巧克力：ChocolateCoffee，咖啡加糖
加冰：SugarIceCoffee&#8230;&#8230;
<br>哎哟，我们发现问题了：这样下去我们的类好多啊。可是咖啡店的老板还不放过我们，他又逼着我们增加蒸汽咖啡、加压咖啡，结果我们发现，每增加一种新的类型，我们的类好像是成几何级数增加，我们都要疯了。
<br>这个例子向我们展示了继承的第二个缺点，会使得我们的子类快速的膨胀下去，达到惊人的数量。
<br>怎么办？我们的Decorator模式找到了组合来为我们解决问题。下面我们来看看Decorator模式是怎么来解决这个问题的。
<br>首先是它们的共同接口：
<br>
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <embed src="http://crud0906.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=package%20decorator%3B%0A%0Ainterface%20Product%20%7B%0Apublic%20double%20money()%3B%0A%7D%0A%0A%2F%2F%E5%92%96%E5%95%A1%E7%B1%BB%EF%BC%9A%0Aclass%20Coffee%20implements%20Product%20%7B%0Apublic%20double%20money()%20%7B%0A%20%20%20%20return%2012%3B%0A%7D%0A%7D%0A%0A%2F%2F%E5%8A%A0%E7%B3%96%EF%BC%9A%0Aclass%20Sugar%20implements%20Product%20%7B%0Aprivate%20Product%20product%3B%0A%0Apublic%20Sugar(Product%20product)%20%7B%0A%20%20%20%20this.product%20%3D%20product%3B%0A%7D%0A%0Apublic%20double%20money()%20%7B%0A%20%20%20%20return%20product.money()%20%2B%202%3B%0A%7D%0A%7D%0A%0A%2F%2F%E5%8A%A0%E5%86%B0%EF%BC%9A%0Aclass%20Ice%20implements%20Product%20%7B%0Aprivate%20Product%20product%3B%0A%0Apublic%20Ice(Product%20product)%20%7B%0A%20%20%20%20this.product%20%3D%20product%3B%0A%7D%0A%0Apublic%20double%20money()%20%7B%0A%20%20%20%20return%20product.money()%20%2B%201.5%3B%0A%7D%0A%7D%0A%0A%2F%2F%E5%8A%A0%E5%A5%B6%EF%BC%9A%0Aclass%20Milk%20implements%20Product%20%7B%0Aprivate%20Product%20product%3B%0A%0Apublic%20Milk(Product%20product)%20%7B%0A%20%20%20%20this.product%20%3D%20product%3B%0A%7D%0A%0Apublic%20double%20money()%20%7B%0A%20%20%20%20return%20product.money()%20%2B%204.0%3B%0A%7D%0A%7D%0A%0A%2F%2F%E5%8A%A0%E5%B7%A7%E5%85%8B%E5%8A%9B%EF%BC%9A%0Aclass%20Chocolate%20implements%20Product%20%7B%0Aprivate%20Product%20product%3B%0A%0Apublic%20Chocolate(Product%20product)%20%7B%0A%20%20%20%20this.product%20%3D%20product%3B%0A%7D%0A%0Apublic%20double%20money()%20%7B%0A%20%20%20%20return%20product.money()%20%2B%205.5%3B%0A%7D%0A%7D%0Apublic%20class%20DecoratorModel%7B%0Apublic%20static%20void%20main(String%20%5B%5D%20args)%7B%0A%20%20%20%20Product%20coffee%20%3D%20new%20Coffee()%3B%0A%20%20%20%20Product%20sugarCoffee%20%3D%20new%20Sugar(coffee)%3B%0A%20%20%20%20Product%20sugarmilkCoffee%20%3D%20new%20Milk(sugarCoffee)%3B%0A%20%20%20%20System.out.println(%22%E5%8A%A0%E7%B3%96%E5%92%96%E5%95%A1%EF%BC%9A%22%2BsugarCoffee.money())%3B%0A%20%20%20%20System.out.println(%22%E5%8A%A0%E7%B3%96%E5%8A%A0%E5%A5%B6%E5%92%96%E5%95%A1%EF%BC%9A%22%2BsugarmilkCoffee.money())%3B%0A%7D%0A%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></div>
</div>
<ol class="dp-j" start="1">
    <li><span><span class="keyword">package</span><span>&nbsp;decorator;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">interface</span><span>&nbsp;Product&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">double</span><span>&nbsp;money();&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="comment">//咖啡类：</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">class</span><span>&nbsp;Coffee&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Product&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">double</span><span>&nbsp;money()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="number">12</span><span>;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="comment">//加糖：</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">class</span><span>&nbsp;Sugar&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Product&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">private</span><span>&nbsp;Product&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Sugar(Product&nbsp;product)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.product&nbsp;=&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">double</span><span>&nbsp;money()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;product.money()&nbsp;+&nbsp;</span><span class="number">2</span><span>;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="comment">//加冰：</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">class</span><span>&nbsp;Ice&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Product&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">private</span><span>&nbsp;Product&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Ice(Product&nbsp;product)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.product&nbsp;=&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">double</span><span>&nbsp;money()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;product.money()&nbsp;+&nbsp;</span><span class="number">1.5</span><span>;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="comment">//加奶：</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">class</span><span>&nbsp;Milk&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Product&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">private</span><span>&nbsp;Product&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Milk(Product&nbsp;product)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.product&nbsp;=&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">double</span><span>&nbsp;money()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;product.money()&nbsp;+&nbsp;</span><span class="number">4.0</span><span>;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="comment">//加巧克力：</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">class</span><span>&nbsp;Chocolate&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Product&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">private</span><span>&nbsp;Product&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;Chocolate(Product&nbsp;product)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.product&nbsp;=&nbsp;product;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">double</span><span>&nbsp;money()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;product.money()&nbsp;+&nbsp;</span><span class="number">5.5</span><span>;&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;DecoratorModel{&nbsp;&nbsp;</span></span></li>
    <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String&nbsp;[]&nbsp;args){&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;Product&nbsp;coffee&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Coffee();&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;Product&nbsp;sugarCoffee&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Sugar(coffee);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;Product&nbsp;sugarmilkCoffee&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Milk(sugarCoffee);&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="string">"加糖咖啡："</span><span>+sugarCoffee.money());&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="string">"加糖加奶咖啡："</span><span>+sugarmilkCoffee.money());&nbsp;&nbsp;</span></span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<pre style="display: none;" name="code" class="java">package decorator;
interface Product {
public double money();
}
//咖啡类：
class Coffee implements Product {
public double money() {
return 12;
}
}
//加糖：
class Sugar implements Product {
private Product product;
public Sugar(Product product) {
this.product = product;
}
public double money() {
return product.money() + 2;
}
}
//加冰：
class Ice implements Product {
private Product product;
public Ice(Product product) {
this.product = product;
}
public double money() {
return product.money() + 1.5;
}
}
//加奶：
class Milk implements Product {
private Product product;
public Milk(Product product) {
this.product = product;
}
public double money() {
return product.money() + 4.0;
}
}
//加巧克力：
class Chocolate implements Product {
private Product product;
public Chocolate(Product product) {
this.product = product;
}
public double money() {
return product.money() + 5.5;
}
}
public class DecoratorModel{
public static void main(String [] args){
Product coffee = new Coffee();
Product sugarCoffee = new Sugar(coffee);
Product sugarmilkCoffee = new Milk(sugarCoffee);
System.out.println("加糖咖啡："+sugarCoffee.money());
System.out.println("加糖加奶咖啡："+sugarmilkCoffee.money());
}
}</pre>
<br>我们来看客户端的调用。
<br>如果顾客想要黑咖啡，调用如下：
<br>Product prod = new Coffee();
<br>System.out.println(prod.money());
<br>如果顾客需要加冰咖啡，调用如下：
<br>Product prod = new Ice(new Coffee());
<br>System.out.println(prod.money());
<br>如果顾客想要加糖加冰加奶加巧克力咖啡，调用如下：
<br>Product prod = new Chocolate(new Milk(new Ice(new Sugar())));
<br>System.out.println(prod.money());
<br>通过上面的例子，我们可以看到组合的又一个很优越的好处：能够在运行期创建新的对象。如上面我们的加冰咖啡，我们没有这个类，却能通过组合在运行期创建该对象，这的确大大的增加了我们程序的灵活性。
<br>如果咖啡店的老板再要求你增加加压咖啡，你就不会再担心了，只给他增加了一个类就解决了所有的问题。<img src ="http://www.cppblog.com/samofweb/aggbug/107687.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-02-11 07:25 <a href="http://www.cppblog.com/samofweb/archive/2010/02/11/107687.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OOD Basic Principles - OOD六大原则</title><link>http://www.cppblog.com/samofweb/archive/2010/02/11/107686.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Wed, 10 Feb 2010 23:22:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/02/11/107686.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/107686.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/02/11/107686.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/107686.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/107686.html</trackback:ping><description><![CDATA[<h3><a  href="http://crud0906.javaeye.com/blog/574822">OOD六大原则</a></h3>
<strong>文章分类:<a  href="http://www.javaeye.com/blogs/category/tech" style="text-decoration: none; padding-right: 10px;">综合技术</a></strong>
<div class="blog_content">
面向对象设计的六大原则
<br>1.开放封闭原则（复用性强，易扩展）
<br>2.依赖倒转原则（依赖于抽象，而不是具体的实现，面向接口（抽象）编程）
<br>3.里氏代换原则（子类型必须能够替换它的基类型。子类只能继承或重写父类的方法，不能有父类中没有定义的方法）
<br>4.多用组合少用继承（适配器模式）
<br>5.迪米特法则（最少知识原则，只和朋友通信，不跟陌生人打交道，门面模式）
<br>6.接口隔离原则（接口不能臃肿，一个接口相当于一个角色，如果一个类实现一个接口时从中获取了不需要的方法，那么这个接口设计的不合理，应该被细分）
<br>
<br>
<br>牢记原则，结合设计模式去体会！设计模式可以忘记，但原则不能忘记！
</div><img src ="http://www.cppblog.com/samofweb/aggbug/107686.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-02-11 07:22 <a href="http://www.cppblog.com/samofweb/archive/2010/02/11/107686.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Good website for C++ programmer</title><link>http://www.cppblog.com/samofweb/archive/2010/01/07/105058.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Thu, 07 Jan 2010 01:50:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/01/07/105058.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/105058.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/01/07/105058.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/105058.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/105058.html</trackback:ping><description><![CDATA[Please check this ordinary but interesting website to find what you like and what you definitely want for programming:<br><br><a  href="http://www.goingware.com/tips">http://www.goingware.com/tips</a><br><br>enjoy~<br><br> <img src ="http://www.cppblog.com/samofweb/aggbug/105058.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-01-07 09:50 <a href="http://www.cppblog.com/samofweb/archive/2010/01/07/105058.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++类 变量初始化</title><link>http://www.cppblog.com/samofweb/archive/2010/01/06/104901.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Wed, 06 Jan 2010 05:45:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/01/06/104901.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/104901.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/01/06/104901.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/104901.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/104901.html</trackback:ping><description><![CDATA[<h1 style="color: #000000;" class="title_txt"><cite class="fav_csdnstylebykimi"> </cite>
</h1>
<div style="color: #000000;" class="blogstory">
<script type="text/javascript">
document.body.oncopy = function() {
if (window.clipboardData) {
setTimeout(function() {
var text = clipboardData.getData("text");
if (text && text.length > 300) {
text = text + "\r\n\n本文来自CSDN博客，转载请标明出处：" + location.href;
clipboardData.setData("text", text);
}
}, 100);
}
}
</script>
<script type="text/javascript">                        function StorePage() { d = document; t = d.selection ? (d.selection.type != 'None' ? d.selection.createRange().text : '') : (d.getSelection ? d.getSelection() : ''); void (keyit = window.open('http://www.365key.com/storeit.aspx?t=' + escape(d.title) + '&u=' + escape(d.location.href) + '&c=' + escape(t), 'keyit', 'scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes')); keyit.focus(); }</script>
<h4 class="beTitle">C++为类中提供<a name="baidusnap2"></a>
</h4>
<h4 class="beTitle">类对象的构造顺序是这样的：<br>1.分配内存，调用构造函数时，隐式／显示的<strong style="background-color: #880000;">初始化</strong>各数据成员<br>2.进入构造函数后在构造函数中执行一般计算</h4>
<h4 class="beTitle">&nbsp; 1.类里面的任何<a name="baidusnap2"></a>
<div id="msgcns!A34683C50FDB4291!379" class="bvMsg">
<div>到此，我的问题解决。但是我还想趁机复习一下<strong style="background-color: #ffff66;">C++类</strong>的<strong style="background-color: #880000;">初始化</strong>：<br>&nbsp; 1.<strong style="background-color: #880000;">初始化</strong>列表：CSomeClass::CSomeClass() : x(0), y(1){}<br>&nbsp; 2.类外<strong style="background-color: #880000;">初始化</strong>：int CSomeClass::myVar=3;<br>&nbsp; 3.const常量定义必须<strong style="background-color: #880000;">初始化</strong>，<strong style="background-color: #ffff66;">C++类</strong>里面使用<strong style="background-color: #880000;">初始化</strong>列表;<br>&nbsp; 4.<strong style="background-color: #ffff66;">C++类</strong>不能定义常量<strong style="background-color: #ff66ff;">数组</strong>。<br>&nbsp; <br>关于const，复习一下常量指针：&nbsp; <br>&nbsp; 如果const位于星号的左侧，则const就是用来修饰指针所指向的变量，即指针指向为常量；如果const位于星号的右侧，const就是修饰指针本身，即指针本身是常量。</div>
<div>
<p>c++各种不同<strong style="background-color: #ffff66;">类</strong>型成员根据是否static 、时候const<strong style="background-color: #ffff66;">类</strong>型的<strong style="background-color: #ff9999;">初始化</strong>方法不尽相同，java的语法就没有这么复杂，怪的得那么多人都跑去学Java了。以前面试时被人问到这个问题回答不出来，写代码时也经常搞乱了，这里翻了下书，总结一下。</p>
<p>-----------------Test.h----------------------------</p>
<p><span style="background-color: #cc99ff;">#pragma once</span></p>
<p><span style="background-color: #333399;"><span style="background-color: #cc99ff;"><span style="background-color: #cc99ff;">class Test</span><br>{<br>private :<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; var1;<br>// int&nbsp;&nbsp; var11= 4; 错误的<strong style="background-color: #ff9999;">初始化</strong>方法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const int&nbsp;&nbsp; var2 ;<br>&nbsp;&nbsp; //const int&nbsp;&nbsp; var22 =22222; 错误的<strong style="background-color: #ff9999;">初始化</strong>方法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static int&nbsp;&nbsp; var3;<br>// static int&nbsp;&nbsp; var3333=33333; 错误，只有静态常量成员才能直接赋值来<strong style="background-color: #ff9999;">初始化</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static const int&nbsp;&nbsp; var4=4444; //正确，静态常量成员可以直接<strong style="background-color: #ff9999;">初始化</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static const int&nbsp;&nbsp; var44;<br>public:<br>Test(void);<br>~Test(void);<br>};</span><br></span>--------------------Test.cpp-----------------------------------</p>
<p><span style="background-color: #cc99ff;">#include ".\test.h"</span></p>
<p><span style="background-color: #cc99ff;">int Test::var3 = 3333333; //静态成员的 正确的<strong style="background-color: #ff9999;">初始化</strong>方法</span></p>
<p><span style="background-color: #cc99ff;">//int Test::var1 = 11111;; 错误 静态成员才能<strong style="background-color: #ff9999;">初始化</strong><br>//int Test::var2 = 22222; 错误<br>//int Test::var44 = 44444; // 错误的方法，提示重定义<br>Test::Test(void) :var1(11111),var2(22222)&nbsp;&nbsp; //正确的<strong style="background-color: #ff9999;">初始化</strong>方法 ， var3(33333) 不能在这里<strong style="background-color: #ff9999;">初始化</strong><br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var1 =11111; //正确, 普通变量也可以在这里<strong style="background-color: #ff9999;">初始化</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //var2 = 222222; 错误，因为常量不能赋值，只能在 &#8220;constructor initializer （构造函数的<strong style="background-color: #ff9999;">初始化</strong>列表）&#8221; 那里<strong style="background-color: #ff9999;">初始化</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; var3 =44444;&nbsp;&nbsp; //这个赋值时正确的，不过因为所有对象一个静态成员，所以会影响到其他的，这不能叫做<strong style="background-color: #ff9999;">初始化</strong>了吧<br>}</span></p>
<p><span style="background-color: #cc99ff;">Test::~Test(void)<br>{<br>}</span></p>
</div>
</div>
</h4>
</div><img src ="http://www.cppblog.com/samofweb/aggbug/104901.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-01-06 13:45 <a href="http://www.cppblog.com/samofweb/archive/2010/01/06/104901.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++'s 模板</title><link>http://www.cppblog.com/samofweb/archive/2010/01/06/104900.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Wed, 06 Jan 2010 05:30:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/01/06/104900.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/104900.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/01/06/104900.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/104900.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/104900.html</trackback:ping><description><![CDATA[<p style="text-indent: -18pt; margin-left: 18pt;">模板就是实现代码重用机制的一种工具，它可以实现类型参数化，即把类型定义为参数， 从而实现了真正的代码可重用性。模版可以分为两类，一个是函数模版，另外一个是类模版。 </p>
<p style="text-indent: -18pt; margin-left: 18pt;"><strong><span style="font-size: 14pt;"><span>1.<span> </span></span></span></strong><strong><span style="font-size: 14pt;">模板的概念</span></strong></p>
<p>我们已经学过<strong><span style="color: red;">重载<span>(Overloading)</span></span></strong>，对重载函数而言<span>,C++</span>的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如，为<span style="color: red;">求两个数的最大值</span>，我们定义<span>MAX()</span>函数需要对不同的数据类型分别定义不同<strong><span style="color: red;">重载<span>(Overload)</span></span></strong>版本。</p>
<p><span style="color: green;">//</span><span style="color: green;">函数<span>1.</span></span></p>
<p><span>int max(<span style="color: red;">int</span> x,<span style="color: red;">int</span> y);<br>{return(x&gt;y)?x:y ;}</span></p>
<p><span style="color: green;">//</span><span style="color: green;">函数<span>2.</span></span><span><br>float max( <span style="color: red;">float</span> x,<span style="color: red;">float</span> y){<br>return (x&gt;y)? x:y ;}</span></p>
<p><span style="color: green;">//</span><span style="color: green;">函数<span>3.</span></span><span><br>double max(<span style="color: red;">double</span> x,<span style="color: red;">double</span> y)<br>{return (c&gt;y)? x:y ;}</span></p>
<p>但如果在主函数中，我们分别定义了<span> char a,b; </span>那么在执行<span>max(a,b);</span>时 程序就会出错，因为我们没有定义<span>char</span>类型的重载版本。</p>
<p>现在，我们再重新审视上述的<span>max()</span>函数，它们都具有同样的功能，即求两个数的最大值，能否只写一套代码解决这个问题呢？这样就会避免因重载函数定义不 全面而带来的调用错误。为解决上述问题<span>C++</span>引入模板机制，<strong><span style="color: red;">模板定义：模板就是实现代码重用机制的一种工具，它可以实现类型参数化，即把类型定义为参数， 从而实现了真正的代码可重用性。模版可以分为两类，一个是函数模版，另外一个是类模版。</span></strong></p>
<p style="text-indent: -18pt; margin-left: 18pt;"><strong><span><span>2.<span>&nbsp;&nbsp; </span></span></span></strong><strong><span style="font-size: 14pt;">函数模板的写法</span></strong></p>
<p>函数模板的一般形式如下：</p>
<p style="line-height: 13pt;"><em><span style="color: green;">Template &lt;<strong>class</strong></span><span style="color: green;">或者也可以用<strong><span>typename</span></strong><span> T&gt;</span></span></em></p>
<p style="line-height: 13pt;"><em><span style="color: green;">返回类型 函数名（形参表）<span><br>{//</span>函数定义体<span> }</span></span></em></p>
<p><strong><span style="color: red;">说明：<span> template</span>是一个声明模板的关键字，表示声明一个模板关键字<span>class</span>不能省略，如果类型形参多余一个 ，每个形参前都要加<span>class &lt;</span>类型 形参表<span>&gt;</span>可以包含基本数据类型可以包含类类型<span>.</span></span></strong></p>
<p><strong><span style="color: red;"></span></strong></p>
<p>请看以下程序<span>:</span></p>
<p><strong><span>//Test.cpp</span></strong></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">#include</span><span style="font-size: 9pt;"> <span style="color: #a31515;">&lt;iostream&gt;</span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">using</span><span style="font-size: 9pt;"> std::cout;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">using</span><span style="font-size: 9pt;"> std::endl;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: green; font-size: 9pt;">//</span><span style="color: green; font-size: 9pt;">声明一个函数模版<span>,</span>用来比较输入的两个相同数据类型的参数的大小，<span>class</span>也可以被<span>typename</span>代替，</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: green; font-size: 9pt;">//T</span><span style="color: green; font-size: 9pt;">可以被任何字母或者数字代替。</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">template</span><span style="font-size: 9pt;"> &lt;<span style="color: blue;">class</span> T&gt;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">T min(T x,T y)</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">{ <span style="color: blue;">return</span>(x&lt;y)?x:y;}</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">void</span><span style="font-size: 9pt;"> main( )</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">{ </span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">int</span> n1=2,n2=10;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">double</span> d1=1.5,d2=5.6;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>cout&lt;&lt; <span style="color: #a31515;">"</span></span><span style="color: #a31515; font-size: 9pt;">较小整数<span>:"</span></span><span style="font-size: 9pt;">&lt;&lt;min(n1,n2)&lt;&lt;endl;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>cout&lt;&lt; <span style="color: #a31515;">"</span></span><span style="color: #a31515; font-size: 9pt;">较小实数<span>:"</span></span><span style="font-size: 9pt;">&lt;&lt;min(d1,d2)&lt;&lt;endl;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>system(<span style="color: #a31515;">"PAUSE"</span>);</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">}</span></p>
<p style="text-align: center;" align="center">程序运行结果：　<span> </span></p>
<p>&nbsp;</p>
<p>程序分析：<span>main()</span>函数中定义了两个整型变量<span>n1 , n2 </span>两个双精度类型变量<span>d1 , d2</span>然后调用<span>min( n1, n2); </span>即实例化函数模板<span>T min(T x, T y)</span>其中Ｔ为<span>int</span>型，求出<span>n1,n2</span>中的最小值．同理调用<span>min(d1,d2)</span>时，求出<span>d1,d2</span>中的最小值．</p>
<p style="text-indent: -18pt; margin-left: 18pt;"><strong><span style="font-size: 14pt;"><span>3.<span> </span></span></span></strong><strong><span style="font-size: 14pt;">类模板的写法</span></strong></p>
<p>定义一个类模板：</p>
<p><em><span style="color: green;">Template &lt;<strong> class</strong></span><span style="color: green;">或者也可以用<strong><span>typename</span></strong><span> T &gt;<br>class</span>类名｛<span><br></span>／／类定义．．．．．．<span><br></span>｝；</span></em></p>
<p><strong><span style="color: red;">说明：其中，<span>template</span>是声明各模板的关键字，表示声明一个模板，模板参数可以是一个，也可以是多个。</span></strong></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span>例如：定义一个类模板：</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><strong><span style="font-size: 12pt;">// ClassTemplate.h</span></strong><span><br></span><span style="color: blue; font-size: 9pt;">#ifndef</span><span style="font-size: 9pt;"> ClassTemplate_HH</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">#define</span><span style="font-size: 9pt;"> ClassTemplate_HH</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">template</span><span style="font-size: 9pt;">&lt;<span style="color: blue;">typename</span> T1,<span style="color: blue;">typename</span> T2&gt;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">class</span><span style="font-size: 9pt;"> myClass{</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">private</span><span style="font-size: 9pt;">:</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>T1 I;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>T2 J;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">public</span><span style="font-size: 9pt;">:</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>myClass(T<st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="True" sourcevalue="1" unitname="a">1 a</st1:chmetcnv>, T2 b);<span style="color: green;">//Constructor</span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue;">void</span> show();</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">};</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: green; font-size: 9pt;">//</span><span style="color: green; font-size: 9pt;">这是构造函数</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: green; font-size: 9pt;">//</span><span style="color: green; font-size: 9pt;">注意这些格式</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">template</span><span style="font-size: 9pt;"> &lt;<span style="color: blue;">typename</span> T1,<span style="color: blue;">typename</span> T2&gt;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">myClass&lt;T1,T2&gt;::myClass(T<st1:chmetcnv tcsc="0" numbertype="1" negative="False" hasspace="True" sourcevalue="1" unitname="a">1 a</st1:chmetcnv>,T2 b):I(a),J(b){}</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: green; font-size: 9pt;">//</span><span style="color: green; font-size: 9pt;">这是<span>void show();</span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">template</span><span style="font-size: 9pt;"> &lt;<span style="color: blue;">typename</span> T1,<span style="color: blue;">typename</span> T2&gt;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">void</span><span style="font-size: 9pt;"> myClass&lt;T1,T2&gt;::show()</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">{</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>cout&lt;&lt;<span style="color: #a31515;">"I="</span>&lt;&lt;I&lt;&lt;<span style="color: #a31515;">", J="</span>&lt;&lt;J&lt;&lt;endl;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">}</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">#endif</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><strong><span style="font-size: 12pt;">// Test.cpp</span></strong></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">#include</span><span style="font-size: 9pt;"> <span style="color: #a31515;">&lt;iostream&gt;</span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">#include</span><span style="font-size: 9pt;"> <span style="color: #a31515;">"ClassTemplate.h"</span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">using</span><span style="font-size: 9pt;"> std::cout;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">using</span><span style="font-size: 9pt;"> std::endl;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">void</span><span style="font-size: 9pt;"> main()</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">{</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>myClass&lt;<span style="color: blue;">int</span>,<span style="color: blue;">int</span>&gt; class1(3,5);</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>class1.show();</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>myClass&lt;<span style="color: blue;">int</span>,<span style="color: blue;">char</span>&gt; class2(3,<span style="color: #a31515;">'a'</span>);</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>class2.show();</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>myClass&lt;<span style="color: blue;">double</span>,<span style="color: blue;">int</span>&gt; class3(2.9,10);</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>class3.show();</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>system(<span style="color: #a31515;">"PAUSE"</span>);</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">}</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 12pt;">最后结果显示：</span></p>
<p style="text-align: center;" class="MsoNormal" align="center"><span style="font-size: 12pt;"></span></p>
<p>&nbsp;</p>
<div align="left"><font size="4"><strong>4.非类型模版参数</strong></font><br>
<p><span>一般来说，非类型模板参数可以是常整数（包括枚举）或者指向外部链接对象的指针。</span></p>
<p><span>那么就是说，浮点数是不行的，指向内部链接对象的指针是不行的。</span></p>
<br>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">template</span><span style="font-size: 9pt;">&lt;<span style="color: blue;">typename</span> T, <span style="color: blue;">int</span> MAXSIZE&gt;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="color: blue; font-size: 9pt;">class</span><span style="font-size: 9pt;"> Stack{</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">Private:</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>T elems[MAXSIZE];</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">&#8230;<span></span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">};</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span></span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">Int main()</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">{</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Stack&lt;<span style="color: blue;">int</span>, 20&gt; int20Stack;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Stack&lt;<span style="color: blue;">int</span>, 40&gt; int40Stack;</span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;">&#8230;<span></span></span></p>
<p style="text-align: left;" class="MsoNormal" align="left"><span style="font-size: 9pt;"></span></p>
<p class="MsoNormal"><span style="font-size: 9pt;">};</span></p>
</div><img src ="http://www.cppblog.com/samofweb/aggbug/104900.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-01-06 13:30 <a href="http://www.cppblog.com/samofweb/archive/2010/01/06/104900.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中const用法总结</title><link>http://www.cppblog.com/samofweb/archive/2010/01/06/104897.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Wed, 06 Jan 2010 05:04:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/01/06/104897.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/104897.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/01/06/104897.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/104897.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/104897.html</trackback:ping><description><![CDATA[<p><strong><font size="2">C++中const用法总结</font></strong></p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000" face="Times new roman" size="2"><strong>作者JuKevin</strong></font></span>
</p>
<p style="margin: 6pt 0cm; line-height: 12pt;"><font color="#000000"><font size="2"><strong><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">1. const</font></span><span style="font-size: 10.5pt; font-family: 宋体;">修饰普通变量和指针</span></strong><span style="font-size: 10.5pt;" lang="EN-US"></span></font></font></p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰变量，一般有两种写法：</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">const TYPE value;</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">TYPE const value;</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">这两种写法在本质上是一样的。</span><span style="font-family: 宋体;">它的含义是：</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰的类型为</span><span lang="EN-US"><font face="Times New Roman">TYPE</font></span><span style="font-family: 宋体;">的变量</span><span lang="EN-US"><font face="Times New Roman">value</font></span><span style="font-family: 宋体;">是不可变的。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">对于一个非指针的类型</span><span lang="EN-US"><font face="Times New Roman">TYPE</font></span><span style="font-family: 宋体;">，无论怎么写，都是一个含义，即</span><span lang="EN-US"><font face="Times New Roman">value</font></span><span style="font-family: 宋体;">只不可变。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">例如：</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const int nValue</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">；</span><span style="color: black; letter-spacing: 0.4pt;"><font face="Times New Roman"> <span lang="EN-US"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//nValue</span></font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">是</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span></font>
</p>
<p style="margin: 0cm 0cm 0pt; line-height: 20.1pt; text-align: left;" align="left"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">int const nValue</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">；</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp; </span>// nValue</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">是</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">但是对于指针类型的</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">TYPE</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">，不同的写法会有不同情况，例如：</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">A. const char *pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="letter-spacing: 0.4pt;" lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">B. char * const pContent;</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">C. char const *pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">D. const char* const pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: red; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">对于前三种写法，我们可以换个方式，给其加上括号</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">A. const (char) *pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="letter-spacing: 0.4pt;" lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">B. (char*) const pContent;</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">C. (char) const *pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">这样就一目了然。根据对于</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">修饰非指针变量的规则，很明显，</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">A=C.</font></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">- </font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">对于</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">A,C, const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">修饰的类型为</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">char</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">的变量</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">*pContent</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">为常量，因此，</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">pContent</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">的内容为常量不可变</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">.</font></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">- </font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">对于</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">B, </font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">其实还有一种写法：</span><span style="letter-spacing: 0.4pt;"><font color="#000000"><font face="Times New Roman"> <span lang="EN-US">const (char*) pContent;</span></font></font></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">含义为：</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">修饰的类型为</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">char*</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">的变量</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">pContent</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">为常量，因此，</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">pContent</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">指针本身为常量不可变</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">.</font></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">- </font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">对于</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">D, </font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">其实是</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">A</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">和</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">B</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">的混合体，表示指针本身和指针内容两者皆为常量不可变</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">总结</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">:</font></span></font>
</p>
<p style="margin: 0cm 0cm 0pt 19.5pt; text-indent: -19.5pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><span><font face="Times New Roman">(1)<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></font></span></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">指针本身是常量不可变</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="letter-spacing: 0.4pt;" lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">(char*) const pContent;</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font face="Times New Roman"><font size="2"><span style="letter-spacing: 0.4pt;" lang="EN-US">const (char*) pContent;</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt 19.5pt; text-indent: -19.5pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><span><font face="Times New Roman">(2)<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></font></span></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">指针所指向的内容是常量不可变</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">const (char) *pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">(char) const *pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt 19.5pt; text-indent: -19.5pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><span><font face="Times New Roman">(3)<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp; </span></font></span></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">两者都不可变</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman"><font size="2">const char* const pContent;</font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">还有其中区别方法：</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">沿着</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">*</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">号划一条线，</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">如果</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">位于</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">*</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">的左侧，则</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">就是用来修饰指针所指向的变量，即指针指向为常量；</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">如果</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">位于</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">*</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">的右侧，</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">就是修饰指针本身，即指针本身是常量。</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font> <br>
</p>
<p style="margin: 6pt 0cm; line-height: 12pt;"><font color="#000000"><font size="2"><strong><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">2. const</font></span><span style="font-size: 10.5pt; font-family: 宋体;">修饰函数参数</span></strong><span style="font-size: 10.5pt;" lang="EN-US"></span></font></font></p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰函数参数是它最广泛的一种用途，它表示函数体中不能修改参数的值</span><span lang="EN-US"><font face="Times New Roman">(</font></span><span style="font-family: 宋体;">包括参数本身的值或者参数其中包含的值</span><span lang="EN-US"><font face="Times New Roman">)</font></span><span style="font-family: 宋体;">。它可以很好</span><span lang="EN-US"></span></font></font> <br>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">void function(const int Var); //</font></span><span style="font-family: 宋体;">传递过来的参数在函数内不可以改变</span><span lang="EN-US"><font face="Times New Roman">(</font></span><span style="font-family: 宋体;">无意义，因为</span><span lang="EN-US"><font face="Times New Roman">Var</font></span><span style="font-family: 宋体;">本身就是形参</span><span lang="EN-US"><font face="Times New Roman">)</font></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">void function(const char* Var); //</font></span><span style="font-family: 宋体;">参数指针所指内容为常量不可变</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">void function(char* const Var); //</font></span><span style="font-family: 宋体;">参数指针本身为常量不可变</span><span lang="EN-US"><font face="Times New Roman">(</font></span><span style="font-family: 宋体;">也无意义，</span><span><font face="Times New Roman"> </font></span><span style="font-family: 宋体;">因为</span><span lang="EN-US"><font face="Times New Roman">char* Var</font></span><span style="font-family: 宋体;">也是形参</span><span lang="EN-US"><font face="Times New Roman">)</font></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000" face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">参数为引用，为了增加效率同时防止修改。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">修饰引用参数时：</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">void function(const Class&amp; Var);//</font></span><span style="font-family: 宋体;">引用参数在函数内不可以改变</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">void function(const TYPE&amp; Var); //</font></span><span style="font-family: 宋体;">引用参数在函数内为常量不可变</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000" face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 6pt 0cm; line-height: 12pt;"><font color="#000000"><font size="2"><strong><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">3. const </font></span><span style="font-size: 10.5pt; font-family: 宋体;">修饰函数返回值</span></strong><span style="font-size: 10.5pt;" lang="EN-US"></span></font></font></p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰函数返回值其实用的并不是很多，它的含义和</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰普通变量以及指针的含义基本相同。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">(1) const int fun1() </font></span><span style="font-family: 宋体;">这个其实无意义，因为参数返回本身就是赋值。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">(2) const int * fun2() </font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">调用时</span><span lang="EN-US"><font face="Times New Roman"> const int *pValue = fun2();</font></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">我们可以把</span><span lang="EN-US"><font face="Times New Roman">fun2()</font></span><span style="font-family: 宋体;">看作成一个变量，那么就是我们上面所说的</span><span lang="EN-US"><font face="Times New Roman">1.(1)</font></span><span style="font-family: 宋体;">的写法，即指针内容不可变。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">(3) int* const fun3() </font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">调用时</span><span lang="EN-US"><font face="Times New Roman"> int * const pValue = fun2();</font></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">我们可以把</span><span lang="EN-US"><font face="Times New Roman">fun2()</font></span><span style="font-family: 宋体;">看作成一个变量，那么就是我们上面所说的</span><span lang="EN-US"><font face="Times New Roman">1.(2)</font></span><span style="font-family: 宋体;">的写法，即指针本身不可变。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 6pt 0cm; line-height: 12pt;"><font color="#000000"><font size="2"><strong><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">4. const</font></span><span style="font-size: 10.5pt; font-family: 宋体;">修饰类对象</span><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">/</font></span><span style="font-size: 10.5pt; font-family: 宋体;">对象指针</span><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">/</font></span><span style="font-size: 10.5pt; font-family: 宋体;">对象引用</span></strong><span style="font-size: 10.5pt;" lang="EN-US"></span></font></font></p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰类对象表示该对象为常量对象，其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰的对象，该对象的任何非</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">成员函数都不能被调用，因为任何非</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">成员函数会有修改成员变量的企图。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">例如：</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">class AAA</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">{<br><span>&nbsp;&nbsp; </span>void func1();</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt; text-indent: 15.75pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">void func2() const;</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">}</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">const AAA aObj;</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">aObj.func1(); </font></span><span style="font-family: 宋体;">&#215;</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">aObj.func2(); </font></span><span style="font-family: 宋体;">正确</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000" face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">const AAA* aObj = new AAA();</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">aObj-&gt;func1(); </font></span><span style="font-family: 宋体;">&#215;</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">aObj-&gt;func2(); </font></span><span style="font-family: 宋体;">正确</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000" face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 6pt 0cm; line-height: 12pt;"><font color="#000000"><font size="2"><strong><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">5. const</font></span><span style="font-size: 10.5pt; font-family: 宋体;">修饰成员变量</span></strong><span style="font-size: 10.5pt;" lang="EN-US"></span></font></font></p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体;" lang="EN-US">const</span><span style="color: black; font-family: 宋体;">修饰类的成员函数，表示成员常量，不能被修改，同时它只能在初始化列表中赋值。<span lang="EN-US"></span></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2">class A</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2">{</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2"><span>&nbsp;&nbsp; </span>&#8230;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体;" lang="EN-US"><span>&nbsp;&nbsp; </span>const int nValue;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>//</span><span style="color: black; font-family: 宋体;">成员常量不能被修改<span lang="EN-US"></span></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2"><span>&nbsp;&nbsp; </span>&#8230;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; font-family: 宋体;" lang="EN-US"><span>&nbsp;&nbsp; </span>A(int x): nValue(x) {}; //</span><span style="color: black; font-family: 宋体;">只能在初始化列表中赋值<span lang="EN-US"></span></span></font>
</p>
<p style="margin: 0cm 0cm 0pt; text-indent: 5.25pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2">}</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="font-family: 宋体;" lang="EN-US"><font color="#000000" size="2">&nbsp;</font></span>
</p>
<p style="margin: 6pt 0cm; line-height: 12pt;"><font color="#000000"><font size="2"><strong><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">6. const</font></span><span style="font-size: 10.5pt; font-family: 宋体;">修饰成员函数</span></strong><span style="font-size: 10.5pt;" lang="EN-US"></span></font></font></p>
<p style="margin: 0cm 0cm 0pt;"><font size="2"><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">修饰类的成员函数，则该成员函数不能修改类中任何非</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"><font face="Times New Roman">const</font></span><span style="color: black; font-family: 宋体; letter-spacing: 0.4pt;">成员函数。一般写在函数的最后来修饰。</span><span style="color: black; letter-spacing: 0.4pt;" lang="EN-US"></span></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000" face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2">class A</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2">{</font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><span style="color: black; font-family: 宋体;" lang="EN-US"><font size="2"><span>&nbsp;&nbsp; </span>&#8230;</font></span>
</p>
<p style="margin: 0cm 0cm 0pt 132.1pt; text-indent: -115.5pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;" lang="EN-US">void function()const; //</span><span style="font-family: 宋体;">常成员函数<span lang="EN-US">, </span>它不改变对象的成员变量<span lang="EN-US">. </span>也不能调用类中任何非<span lang="EN-US">const</span>成员函数。<span lang="EN-US"></span></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt; text-indent: 5.25pt;"><span lang="EN-US"><font color="#000000"><font face="Times New Roman"><font size="2">}</font></font></font></span>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span style="font-family: 宋体;">对于</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">类对象</span><span lang="EN-US"><font face="Times New Roman">/</font></span><span style="font-family: 宋体;">指针</span><span lang="EN-US"><font face="Times New Roman">/</font></span><span style="font-family: 宋体;">引用，只能调用类的</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">成员函数，因此，</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">修饰成员函数的最重要作用就是限制对于</span><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">对象的使用。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><font color="#000000" face="Times new roman" size="2">&nbsp;</font></span>
</p>
<p style="margin: 6pt 0cm; line-height: 12pt;"><font color="#000000"><font size="2"><strong><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">7. const</font></span><span style="font-size: 10.5pt; font-family: 宋体;">常量与</span><span style="font-size: 10.5pt;" lang="EN-US"><font face="Times New Roman">define</font></span><span style="font-size: 10.5pt; font-family: 宋体;">宏定义的区别</span></strong><span style="font-size: 10.5pt;" lang="EN-US"></span></font></font></p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">(1) </font></span><span style="font-family: 宋体;">编译器处理方式不同</span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">define</font></span><span style="font-family: 宋体;">宏是在预处理阶段展开。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">常量是编译运行阶段使用。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">(2) </font></span><span style="font-family: 宋体;">类型和安全检查不同</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">define</font></span><span style="font-family: 宋体;">宏没有类型，不做任何类型检查，仅仅是展开。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">常量有具体的类型，在编译阶段会执行类型检查。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">(3) </font></span><span style="font-family: 宋体;">存储方式不同</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">define</font></span><span style="font-family: 宋体;">宏仅仅是展开，有多少地方使用，就展开多少次，不会分配内存。</span><span lang="EN-US"></span></font></font>
</p>
<p style="margin: 0cm 0cm 0pt;"><font color="#000000"><font size="2"><span lang="EN-US"><font face="Times New Roman">const</font></span><span style="font-family: 宋体;">常量会在内存中分配</span><span lang="EN-US"><font face="Times New Roman">(</font></span><span style="font-family: 宋体;">可以是堆中也可以是栈中</span><span lang="EN-US"><font face="Times New Roman">)</font></span><span style="font-family: 宋体;">。</span></font></font> </p><img src ="http://www.cppblog.com/samofweb/aggbug/104897.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-01-06 13:04 <a href="http://www.cppblog.com/samofweb/archive/2010/01/06/104897.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>引用 usage</title><link>http://www.cppblog.com/samofweb/archive/2010/01/06/104896.html</link><dc:creator>SimonHan</dc:creator><author>SimonHan</author><pubDate>Wed, 06 Jan 2010 04:59:00 GMT</pubDate><guid>http://www.cppblog.com/samofweb/archive/2010/01/06/104896.html</guid><wfw:comment>http://www.cppblog.com/samofweb/comments/104896.html</wfw:comment><comments>http://www.cppblog.com/samofweb/archive/2010/01/06/104896.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/samofweb/comments/commentRss/104896.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/samofweb/services/trackbacks/104896.html</trackback:ping><description><![CDATA[<font size="3">引用是C++引入的新语言特性，是C++常用的一个重要内容之一，正确、灵活地使用引用，可以使程序简洁、高效。我在工作
中发现，许多人使用它仅仅是想当然，在某些微妙的场合，很容易出错，究其原由，大多因为没有搞清本源。故在本篇中我将对引用进行详细讨论，希望对大家更好
地理解和使用引用起到抛砖引玉的作用。<br><br>　　引用简介<br><br>　　<font color="#0000ff">引用就是某一变量（目标）的一个别名，对引用的操作与对变量直接操作完全一样。<br><br>　　引用的声明方法：类型标识符 &amp;引用名=目标变量名；<br></font><br>　　【例1】：int a; int &amp;ra=a; //定义引用ra,它是变量a的引用，即别名<br><br>　　<font color="#ff9900">说明：<br></font><br>　　（1）&amp;在此不是求地址运算，而是起标识作用。<br><br>　　（2）类型标识符是指目标变量的类型。<br><br>　　（3）声明引用时，必须同时对其进行初始化。<br><br>　　（4）引用声明完毕后，相当于目标变量名有两个名称，即该目标原名称和引用名，且不能再把该引用名作为其他变量名的别名。<br><br>　　 ra=1; 等价于 a=1; <br><br>　　（5）声明一个引用，不是新定义了一个变量，它只表示该引用名是目标变量名的一个别名，它本身不是一种数据类型，因此引用本身不占存储单元，系统也不给引用分配存储单元。故：对引用求地址，就是对目标变量求地址。&amp;ra与&amp;a相等。<br><br>　　（6）不能建立数组的引用。因为数组是一个由若干个元素所组成的集合，所以无法建立一个数组的别名。<br><br><strong><font color="#ff0000">　　引用应用</font></strong><br><br><strong>　　1、引用作为参数</strong> <br><br>
引用的一个重要作用就是作为函数的参数。以前的C语言中函数参数传递是值传递，如果有大块数据作为参数传递的时候，采用的方案往往是指针，因为这样可以
避免将整块数据全部压栈，可以提高程序的效率。但是现在（C++中）又增加了一种同样有效率的选择（在某些特殊情况下又是必须的选择），就是引用。<br><br>　　【例2】：<br><br>void swap(int &amp;p1, int &amp;p2) //此处函数的形参p1, p2都是引用 <br>{ int p; p=p1; p1=p2; p2=p; } <br><br>　　为在程序中调用该函数，则相应的主调函数的调用点处，直接以变量作为实参进行调用即可，而不需要实参变量有任何的特殊要求。如：对应上面定义的swap函数，相应的主调函数可写为：<br><br>main( )<br>{ <br>　int a,b;<br>　cin&gt;&gt;a&gt;&gt;b; //输入a,b两变量的值<br>　swap(a,b); //直接以变量a和b作为实参调用swap函数 <br>　cout&lt;&lt;a&lt;&lt; ' ' &lt;&lt;b; //输出结果 <br>} <br><br>　　上述程序运行时，如果输入数据10 20并回车后，则输出结果为20 10。<br><br>　<strong><font color="#ff0000">　由【例2】可看出：</font></strong><br><br>　　<font color="#ff00ff">（1）传递引用给函数与传递指针的效果是一样的。这时，被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用，所以在被调函数中对形参变量的操作就是对其相应的目标对象（在主调函数中）的操作。<br><br>
（2）使用引用传递函数的参数，在内存中并没有产生实参的副本，它是直接对实参操作；而使用一般变量传递函数的参数，当发生函数调用时，需要给形参分配
存储单元，形参变量是实参变量的副本；如果传递的是对象，还将调用拷贝构造函数。因此，当参数传递的数据较大时，用引用比用一般变量传递参数的效率和所占
空间都好。<br><br>　　（3）使用指针作为函数的参数虽然也能达到与使用引用的效果，但是，在被调函数中同样要给形参分配存储单元，且需要重复使
用'*指针变量名'的形式进行运算，这很容易产生错误且程序的阅读性较差；另一方面，在主调函数的调用点处，必须用变量的地址作为实参。而引用更容易使
用，更清晰。</font><br><br>　　<font color="#0000ff">如果既要利用引用提高程序的效率，又要保护传递给函数的数据不在函数中被改变，就应使用<strong>常引用</strong>。</font><br><br>　<strong><font color="#ff0000">　2、常引用</font></strong><br><br>　　<strong>常引用声明方式：const 类型标识符 &amp;引用名=目标变量名；<br></strong><br>　　<font color="#0000ff">用这种方式声明的引用，不能通过引用对目标变量的值进行修改,从而使引用的目标成为const，达到了引用的安全性。<br></font><br>　　【例3】： <br><br>int a ;<br>const int &amp;ra=a;<br>ra=1; //错误<br>a=1; //正确 <br><br>　　这不光是让代码更健壮，也有些其它方面的需要。<br><br>　　【例4】：假设有如下函数声明：<br><br>string foo( );<br>void bar(string &amp; s); <br><br>　　那么下面的表达式将是非法的：<br><br>bar(foo( ));<br>bar('hello world'); <br><br>　　原因在于foo( )和'hello world'串都会产生一个临时对象，而在C++中，这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型，这是非法的。</font><br><strong>引用型参数应该在能被定义为const的情况下，尽量定义为const 。<br></strong><br><br><strong><font color="#ff0000">　　3、引用作为返回值</font></strong> <br><br>　　要以引用返回函数值，则函数定义时要按以下格式：<br><br>类型标识符 &amp;函数名（形参列表及类型说明）<br>{函数体}<br><br>　　说明：<br><br>　　（1）以引用返回函数值，定义函数时需要在函数名前加&amp;<br><br>　　（2）用引用返回一个函数值的最大好处是，在内存中不产生被返回值的副本。<br><br>　　【例5】以下程序中定义了一个普通的函数fn1（它用返回值的方法返回函数值），另外一个函数fn2，它以引用的方法返回函数值。<br><br>#include &lt;iostream.h&gt;<br>float temp; //定义全局变量temp<br>float fn1(float r); //声明函数fn1<br>float &amp;fn2(float r); //声明函数fn2<br>float fn1(float r) //定义函数fn1，它以返回值的方法返回函数值<br>{ <br>　temp=(float)(r*r*3.14); <br>　return temp; <br>}<br>float &amp;fn2(float r) //定义函数fn2，它以引用方式返回函数值<br>{ <br>　temp=(float)(r*r*3.14); <br>　return temp;<br>}<br>void main() //主函数<br>{ <br>　float a=fn1(10.0); //第1种情况，系统生成要返回值的副本（即临时变量）<br>　float &amp;b=fn1(10.0); //第2种情况，可能会出错（不同 C++系统有不同规定）<br>　//不能从被调函数中返回一个临时变量或局部变量的引用<br>　float c=fn2(10.0); //第3种情况，系统不生成返回值的副本<br>　//可以从被调函数中返回一个全局变量的引用<br>　float &amp;d=fn2(10.0); //第4种情况，系统不生成返回值的副本<br>　//可以从被调函数中返回一个全局变量的引用<br>　cout&lt;&lt;a&lt;&lt;c&lt;&lt;d;<br>} <br><br>　<strong>　引用作为返回值，必须遵守以下规则：<br></strong><br>　　（1）不能返回局部变量的引用。这条可以参照Effective C++[1]的Item 31。主要原因是局部变量会在函数返回后被销毁，因此被返回的引用就成为了'无所指'的引用，程序会进入未知状态。 <br><br>
（2）不能返回函数内部new分配的内存的引用。这条可以参照Effective C++[1]的Item
31。虽然不存在局部变量的被动销毁问题，可对于这种情况（返回函数内部new分配内存的引用），又面临其它尴尬局面。例如，被函数返回的引用只是作为一
个临时变量出现，而没有被赋予一个实际的变量，那么这个引用所指向的空间（由new分配）就无法释放，造成memory leak。<br><br>
（3）可以返回类成员的引用，但最好是const。这条原则可以参照Effective C++[1]的Item
30。主要原因是当对象的属性是与某种业务规则（business
rule）相关联的时候，其赋值常常与某些其它属性或者对象的状态有关，因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常
量引用（或指针），那么对该属性的单纯赋值就会破坏业务规则的完整性。<br><br>　　（4）引用与一些操作符的重载：<br><br>　　流操作
符&lt;&lt;和&gt;&gt;，这两个操作符常常希望被连续使用，例如：cout &lt;&lt; 'hello' &lt;&lt;
endl;　因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括：返回一个流对象和返回一个流对象指针。但是对于返回
一个流对象，程序必须重新（拷贝）构造一个新的流对象，也就是说，连续的两个&lt;&lt;操作符实际上是针对不同对象的！这无法让人接受。对于返回一
个流指针则不能连续使用&lt;&lt;操作符。因此，返回一个流对象引用是惟一选择。这个唯一选择很关键，它说明了引用的重要性以及无可替代性，也许这
就是C++语言中引入引用这个概念的原因吧。 赋值操作符=。这个操作符象流操作符一样，是可以连续使用的，例如：x = j =
10;或者(x=10)=100;赋值操作符的返回值必须是一个左值，以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。<br><br>　　【例6】 测试用返回引用的函数值作为赋值表达式的左值。<br><br>#include &lt;iostream.h&gt;<br>int &amp;put(int n);<br>int vals[10];<br>int error=-1;<br>void main()<br>{<br>put(0)=10; //以put(0)函数值作为左值，等价于vals[0]=10; <br>put(9)=20; //以put(9)函数值作为左值，等价于vals[9]=10; <br>cout&lt;&lt;vals[0]; <br>cout&lt;&lt;vals[9];<br>} <br>int &amp;put(int n)<br>{<br>if (n&gt;=0 &amp;&amp; n&lt;=9 ) return vals[n]; <br>else { cout&lt;&lt;'subscript error'; return error; }<br>} <br><br>
（5）在另外的一些操作符中，却千万不能返回引用：+-*/ 四则运算符。它们不能返回引用，Effective
C++[1]的Item23详细的讨论了这个问题。主要原因是这四个操作符没有side
effect，因此，它们必须构造一个对象作为返回值，可选的方案包括：返回一个对象、返回一个局部变量的引用，返回一个new分配的对象的引用、返回一
个静态对象引用。根据前面提到的引用作为返回值的三个规则，第2、3两个方案都被否决了。静态对象的引用又因为((a+b) ==
(c+d))会永远为true而导致错误。所以可选的只剩下返回一个对象了。<br><strong><font color="#ff0000">4、引用和多态 <br></font></strong><br>　　引用是除指针外另一个可以产生多态效果的手段。这意味着，一个基类的引用可以指向它的派生类实例。<br><br>　　【例7】： <br><br>class 　A;<br>class 　B：public A{&#8230;&#8230;};<br>B 　b;<br>A 　&amp;Ref = b; // 用派生类对象初始化基类对象的引用<br><br>　　Ref 只能用来访问派生类对象中从基类继承下来的成员，是基类引用指向派生类。如果A类中定义有虚函数，并且在B类中重写了这个虚函数，就可以通过Ref产生多态效果。<br><br>　　<strong><font color="#ff0000">引用总结</font></strong><br><br>　　（1）在引用的使用中，单纯给某个变量取个别名是毫无意义的，引用的目的主要用于在函数参数传递中，解决大块数据或对象的传递效率和空间不如意的问题。<br><br>　　（2）用引用传递函数的参数，能保证参数传递中不产生副本，提高传递的效率，且通过const的使用，保证了引用传递的安全性。<br><br>　　（3）<strong>引用与指针的区别是，</strong>指针通过某个指针变量指向一个对象后，对它所指向的变量间接操作。程序中使用指针，程序的可读性差；而引用本身就是目标变量的别名，对引用的操作就是对目标变量的操作。<br><br>　　（4）使用引用的时机。流操作符&lt;&lt;和&gt;&gt;、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。 <img src ="http://www.cppblog.com/samofweb/aggbug/104896.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/samofweb/" target="_blank">SimonHan</a> 2010-01-06 12:59 <a href="http://www.cppblog.com/samofweb/archive/2010/01/06/104896.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>