﻿<?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++博客-小海豚-随笔分类-C++学习感想</title><link>http://www.cppblog.com/susu/category/1056.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 21 May 2008 10:26:26 GMT</lastBuildDate><pubDate>Wed, 21 May 2008 10:26:26 GMT</pubDate><ttl>60</ttl><item><title>const使用详解</title><link>http://www.cppblog.com/susu/archive/2007/04/06/21391.html</link><dc:creator>学习才能进步</dc:creator><author>学习才能进步</author><pubDate>Fri, 06 Apr 2007 05:36:00 GMT</pubDate><guid>http://www.cppblog.com/susu/archive/2007/04/06/21391.html</guid><wfw:comment>http://www.cppblog.com/susu/comments/21391.html</wfw:comment><comments>http://www.cppblog.com/susu/archive/2007/04/06/21391.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/susu/comments/commentRss/21391.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/susu/services/trackbacks/21391.html</trackback:ping><description><![CDATA[<p>&nbsp;如果const关键字不涉及到指针很好理解，下面是涉及到指针的情况： &nbsp; &nbsp; <br>&nbsp; int &nbsp; b &nbsp; = &nbsp; 500; &nbsp; <br>&nbsp; const &nbsp; int* &nbsp; a &nbsp; = &nbsp; &amp;b; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;[1] &nbsp; <br>&nbsp; int &nbsp; const &nbsp; *a &nbsp; = &nbsp; &amp;b;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [2] &nbsp; <br>&nbsp; int* &nbsp; const &nbsp; a &nbsp; = &nbsp; &amp;b;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;[3] &nbsp; <br>&nbsp; const &nbsp; int* &nbsp; const &nbsp; a &nbsp; = &nbsp; &amp;b;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [4] &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 如果const位于星号的左侧，则const就是用来修饰指针所指向的变量，即指针指向为常量；如果const位于星号的右侧，const就是修饰指针本身，即指针本身是常量。因此，[1]和[2]的情况相同，都是指针所指向的内容为常量（const放在变量声明符的位置无关），这种情况下不允许对内容进行更改操作，如不能*a &nbsp; = &nbsp; 3 &nbsp; ；[3]为指针本身是常量，而指针所指向的内容不是常量，这种情况下不能对指针本身进行更改操作，如a++是错误的；[4]为指针本身和指向的内容均为常量。 &nbsp; <br>&nbsp; 另外const &nbsp; 的一些强大的功能在于它在函数声明中的应用。在一个函数声明中，const &nbsp; 可以修饰函数的返回值，或某个参数；对于成员函数，还可以修饰是整个函数。 &nbsp; <br>&nbsp; 有如下几种情况: &nbsp; <br>&nbsp; A&amp; &nbsp; operator=(const &nbsp; A&amp; &nbsp; a); &nbsp; <br>&nbsp; void &nbsp; fun0(const &nbsp; A* &nbsp; a &nbsp; ); &nbsp; &nbsp; <br>&nbsp; void &nbsp; fun1( &nbsp; ) &nbsp; const; &nbsp; &nbsp; &nbsp; &nbsp; // &nbsp; fun1( &nbsp; ) &nbsp; 为类成员函数 &nbsp; <br>&nbsp; const &nbsp; A &nbsp; fun2( &nbsp; ); &nbsp; <br>&nbsp; ---------------------------------------------------------------------------------- &nbsp; <br>&nbsp; const的初始化 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 先看一下const变量初始化的情况 &nbsp; <br>&nbsp; 1) &nbsp; 非指针const常量初始化的情况： &nbsp; <br>&nbsp; A &nbsp; b; &nbsp; <br>&nbsp; const &nbsp; A &nbsp; a &nbsp; = &nbsp; b; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 2) &nbsp; 指针(引用)const常量初始化的情况： &nbsp; <br>&nbsp; A* &nbsp; d &nbsp; = &nbsp; new &nbsp; A(); &nbsp; <br>&nbsp; const &nbsp; A* &nbsp; c &nbsp; = &nbsp; d; &nbsp; <br>&nbsp; 或者：const &nbsp; A* &nbsp; c &nbsp; = &nbsp; new &nbsp; A(); &nbsp; <br>&nbsp; 引用： &nbsp; <br>&nbsp; A &nbsp; f; &nbsp; <br>&nbsp; const &nbsp; A&amp; &nbsp; e &nbsp; = &nbsp; f; &nbsp; &nbsp; &nbsp; // &nbsp; 这样作e只能访问声明为const的函数，而不能访问一般的成员函数； &nbsp; <br>&nbsp; ---------------------------------------------------------------------------------- &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 作为参数和返回值的const修饰符 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 其实，不论是参数还是返回值，参数传入时候和函数返回的时候，初始化const变量 &nbsp; <br>&nbsp; 1 &nbsp; 修饰参数的const，如 &nbsp; void &nbsp; fun0(const &nbsp; A* &nbsp; a &nbsp; ); &nbsp; void &nbsp; fun1(const &nbsp; A&amp; &nbsp; a); &nbsp; <br>&nbsp; 调用函数的时候，用相应的变量初始化const常量，则在函数体中，按照const所修饰的部分进行常量化，如形参为const &nbsp; A* &nbsp; a，则不能对传递进来的指针的内容进行改变，保护了原指针所指向的内容；如形参为const &nbsp; A&amp; &nbsp; a，则不能对传递进来的引用对象进行改变，保护了原对象的属性。 &nbsp; <br>&nbsp; [注意]：参数const通常用于参数为指针或引用的情况; &nbsp; <br>&nbsp; 2 &nbsp; 修饰返回值的const，如const &nbsp; A &nbsp; fun2( &nbsp; ); &nbsp; const &nbsp; A* &nbsp; fun3( &nbsp; ); &nbsp; <br>&nbsp; 这样声明了返回值后，const按照"修饰原则"进行修饰，起到相应的保护作用。 &nbsp; <br>&nbsp; const &nbsp; Rational &nbsp; operator*(const &nbsp; Rational&amp; &nbsp; lhs, &nbsp; const &nbsp; Rational&amp; &nbsp; rhs) &nbsp; <br>&nbsp; { &nbsp; <br>&nbsp; return &nbsp; Rational(lhs.numerator() &nbsp; * &nbsp; rhs.numerator(), &nbsp; <br>&nbsp; lhs.denominator() &nbsp; * &nbsp; rhs.denominator()); &nbsp; <br>&nbsp; } &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 返回值用const修饰可以防止允许这样的操作发生: &nbsp; <br>&nbsp; Rational &nbsp; a,b; &nbsp; <br>&nbsp; Radional &nbsp; c; &nbsp; <br>&nbsp; (a*b) &nbsp; = &nbsp; c; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 一般用const修饰返回值为对象本身（非引用和指针）的情况多用于二目操作符重载函数并产生新对象的时候。 &nbsp; <br>&nbsp; [总结] &nbsp; 一般情况下，函数的返回值为某个对象时，如果将其声明为const时，多用于操作符的重载。通常，不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。 &nbsp; <br>&nbsp; 原因如下： &nbsp; <br>&nbsp; 如果返回值为某个对象为const（const &nbsp; A &nbsp; test &nbsp; = &nbsp; A &nbsp; 实例）或某个对象的引用为const（const &nbsp; A&amp; &nbsp; test &nbsp; = &nbsp; A实例） &nbsp; ，则返回值具有const属性，则返回实例只能访问类A中的公有（保护）数据成员和const成员函数，并且不允许对其进行赋值操作，这在一般情况下很少用到。 &nbsp; &nbsp; <br>&nbsp; ---------------------------------------------------------------------------------- &nbsp; <br>&nbsp; 类成员函数中const的使用 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 一般放在函数体后，形如：void &nbsp; fun() &nbsp; const; &nbsp; <br>&nbsp; 如果一个成员函数的不会修改数据成员，那么最好将其声明为const，因为const成员函数中不允许对数据成员进行修改，如果修改，编译器将报错，这大大提高了程序的健壮性。 &nbsp; &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; ---------------------------------------------------------------------------------- &nbsp; <br>&nbsp; 使用const的一些建议 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 1 &nbsp; 要大胆的使用const，这将给你带来无尽的益处，但前提是你必须搞清楚原委； &nbsp; <br>&nbsp; 2 &nbsp; 要避免最一般的赋值操作错误，如将const变量赋值，具体可见思考题； &nbsp; <br>&nbsp; 3 &nbsp; 在参数中使用const应该使用引用或指针，而不是一般的对象实例，原因同上； &nbsp; <br>&nbsp; 4 &nbsp; const在成员函数中的三种用法（参数、返回值、函数）要很好的使用； &nbsp; <br>&nbsp; 5 &nbsp; 不要轻易的将函数的返回值类型定为const; &nbsp; <br>&nbsp; 6 &nbsp; 除了重载操作符外一般不要将返回值类型定为对某个对象的const引用;&nbsp;&nbsp;</p>
<h4 class=TextColor1 id=subjcns!5E75F9A72DE37A93!106 style="MARGIN-BOTTOM: 0px">const * 与 * const</h4>
<div id=msgcns!5E75F9A72DE37A93!106>
<div>const *表示指向const对象的指针，可以指向一个const的对象，但是并不是指只能指向一个const对象，指向const对象的指针同样可以指向一个非cons类型的对象。但是const的对象只能由const*类型的指针指向，而不能由普通指针指向。const*类型的指针在使用过程中可以其改变，即可以指向其他对象。</div>
<div>const*类型的指针的真正含义是：如果一个指针是const*类型的指针表示该指针指向的对象不能通过该指针进行修改（对象本身可能通过别的方式进行修改）。&nbsp;</div>
<div>*const expression表示指针(expression)本身是const，即*const类型的指针初始化后不能改变，不能指向别的对象。&nbsp;</div>
<div>char * point_char = new char('e');</div>
<div>const char char_char = 'f';</div>
<div>const char * const_star_char;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 可以不用初始化</div>
<div>char *const&nbsp; star_const_char = point_char;&nbsp;&nbsp;&nbsp; // 必须初始化</div>
<div>const_star_char = &amp;char_char;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // OK</div>
<div>star_const_char = &amp;char_char;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 错误，*const 不可改变</div>
<div>const_star_char = star_const_char;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// OK</div>
<div>star_const_char = const_star_char ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 错误&nbsp;，*const 不可改变<br></div>
</div>
const char* const foo(char const * const str) const<br><br>第一个const表示返回类型为const，也就是不能把此函数的返回值当作左值来使用。<br><br>第二个const表示指针的不可变性，但在这是可以省略，因为返类型已经是const。<br><br>第三个cosnt表示str的常量性，也就其内容是不能改变，可以写在其前面的char的前面。<br><br>第四个cosnt表示str的指针的常量性，也就是此指针不能指向别的地址。<br><br>第五个cosnt表示此函数的常量性（前提是类的成员函数），不能修改所在类的数据成员。<br>
<img src ="http://www.cppblog.com/susu/aggbug/21391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/susu/" target="_blank">学习才能进步</a> 2007-04-06 13:36 <a href="http://www.cppblog.com/susu/archive/2007/04/06/21391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>贝赛莱笔试题(部分)</title><link>http://www.cppblog.com/susu/archive/2007/04/06/21390.html</link><dc:creator>学习才能进步</dc:creator><author>学习才能进步</author><pubDate>Fri, 06 Apr 2007 05:25:00 GMT</pubDate><guid>http://www.cppblog.com/susu/archive/2007/04/06/21390.html</guid><wfw:comment>http://www.cppblog.com/susu/comments/21390.html</wfw:comment><comments>http://www.cppblog.com/susu/archive/2007/04/06/21390.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/susu/comments/commentRss/21390.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/susu/services/trackbacks/21390.html</trackback:ping><description><![CDATA[<div class=item-content>1 在Win32下提供的进程间通信方式有以下几种：
<p>剪贴板Clipboard：在16位时代常使用的方式，CWnd类中提供了支持。 <br>COM/DCOM：通过COM系统的代理存根方式进行进程间数据交换，但只能够表现在对接口函数的调用时传送数据，通过DCOM可以在不同主机间传送数据。 <br>Dynamic Data Exchange (DDE)：在16位时代常使用的方式。 <br>File Mapping：文件映射，在32位系统中提供的新方法，可用来共享内存。 <br>Mailslots：邮件槽，在32位系统中提供的新方法，可在不同主机间交换数据，分为服务器方和客户方，双方可以通过其进行数据交换，在Win9X下只支持邮件槽客户。 <br>Pipes：管道，分为无名管道：在父子进程间交换数据；有名管道：可在不同主机间交换数据，分为服务器方和客户方，在Win9X下只支持有名管道客户。 <br>RPC：远程过程调用，很少使用，原因有两个：复杂而且与UNIX系统的RCP并不完全兼容。但COM/DCOM的调用是建立在RPC的基础上的。 <br>Windows Sockets：网络套接口，可在不同主机间交换数据，分为服务器方和客户方。<br>WM_COPYDATA：通过发送WM_COPYDATA消息并将数据放在参数中来传递数据给其他进程。</p>
<p>2 有关死锁的问题</p>
<ol>
    <li>什么是死锁? <br>答：死锁(deadlock)是指进程之间无限期地互相等待，等待永不发生的事件.</li>
    <li>产生死锁的原因及必要条件是什么？ <br>答：产生死锁的原因：一是系统提供的资源数量有限，不能满足每个进程的使用；二是多道程序运行时，进程推进顺序不合理。 <br>产生死锁的必要条件是：1、互斥条件；2、不可剥夺条件（不可抢占）；3、部分分配；4、循环等待。&nbsp;</li>
    <li>如何预防死锁？ <br>答：根据产生死锁的四个必要条件，只要使其中之一不能成立，死锁就不会出现。为此，可以采取下列三种预防措施： <br>1、采用资源静态分配策略，破坏"部分分配"条件； <br>2、允许进程剥夺使用其他进程占有的资源，从而破坏"不可剥夺"条件； <br>3、采用资源有序分配法，破坏"环路"条件。 </li>
    <li>如何避免死锁？ <br>答：死锁的避免不严格地限制死锁的必要条件的存在，而是系统在系统运行过程中小心地避免死锁的最终发生。最著名的死锁避免算法是银行家算。死锁避免算法需要很大的系统开销。 </li>
    <li>如何检测死锁？ <br>答：解决死锁的另一条途径是死锁检测方法，这种方法对资源的分配不加限制，即允许死锁的发生。但系统定时地运行一个"死锁检测"程序，判断系统是否已发生死锁，若检测到死锁发生则设法加以解除。 </li>
    <li>如何解除死锁？ <br>答：常常采用下面两种方法： <br>1、资源剥夺法；2、撤消进程法</li>
</ol>
<p>3 指针与引用的区别</p>
<p><span><span><span><span>&nbsp;&nbsp;&nbsp;&nbsp;指针与引用看上去完全不同（指针用操作符&#8220;<span>*&#8221;和&#8220;-&gt;&#8221;，引用使用操作符&#8220;. &#8221;），但是它们似乎有相同的功能。指针与引用都是让你间接引用其他对象。你如何决定在什么时候使用指针，在什么时候使用引用呢？</span></span></span></span></span></p>
<p><span>首先，要认识到在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象，但是该变量在某些时候也可能不指向任何对象，这时你应该把变量声明为指针，因为这样你可以赋空值给该变量。相反，如果变量肯定指向一个对象，例如你的设计不允许变量为空，这时你就可以把变量声明为引用。</span></p>
<p><span><span>&nbsp;</span>&#8220;但是，请等一下&#8221;，你怀疑地问，&#8220;这样的代码会产生什么样的后果？&#8221;</span></p>
<p><span>char *pc = 0;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 设置指针为空值 </span></p>
<p><span>char&amp; rc = *pc;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 让引用指向空值</span></p>
<p><span>这是非常有害的，毫无疑问。结果将是不确定的（编译器能产生一些输出，导致任何事情都有可能发生）。应该躲开写出这样代码的人，除非他们同意改正错误。如果你担心这样的代码会出现在你的软件里，那么你最好完全避免使用引用，要不然就去让更优秀的程序员去做。我们以后将忽略一个引用指向空值的可能性。</span></p>
<p><span>因为引用肯定会指向一个对象，在<span>C＋＋里，引用应被初始化。</span></span></p>
<p><span>string&amp; rs;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 错误，引用必须被初始化</span></p>
<p><span>string s("xyzzy");</span></p>
<p><span>string&amp; rs = s;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 正确，rs指向s</span></p>
<p><span>指针没有这样的限制。</span></p>
<p><span>string *ps;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 未初始化的指针</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;</span>// 合法但危险</span></p>
<p><span>不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。</span></p>
<p><span>void printDouble(const double&amp; rd)</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>cout &lt;&lt; rd;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 不需要测试rd,它</span></p>
<p><span>}<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 肯定指向一个double值</span></p>
<p><span>相反，指针则应该总是被测试，防止其为空：</span></p>
<p><span>void printDouble(const double *pd)</span></p>
<p><span>{</span></p>
<p><span><span>&nbsp; </span>if (pd) {<span>&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>// 检查是否为NULL</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>cout &lt;&lt; *pd;</span></p>
<p><span><span>&nbsp;</span>}</span></p>
<p><span>}</span></p>
<p><span>指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象，以后不能改变。</span></p>
<p><span>string s1("Nancy");</span></p>
<p><span>string s2("Clancy"); </span></p>
<p><span>string&amp; rs = s1;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// rs 引用 s1</span></p>
<p><span>string *ps = &amp;s1;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// ps 指向 s1 </span></p>
<p><span>rs = s2;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// rs 仍旧引用s1,</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 但是 s1的值现在是</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// "Clancy"</span></p>
<p><span>ps = &amp;s2;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// ps 现在指向 s2;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// s1 没有改变</span></p>
<p><span>总的来说，在以下情况下你应该使用指针，一是你考虑到存在不指向任何对象的可能（在这种情况下，你能够设置指针为空），二是你需要能够在不同的时刻指向不同的对象（在这种情况下，你能改变指针的指向）。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向，那么你应该使用引用。</span></p>
<p><span>还有一种情况，就是当你重载某个操作符时，你应该使用引用。最普通的例子是操作符<span>[]。这个操作符典型的用法是返回一个目标对象，其能被赋值。</span></span></p>
<p><span>vector&lt;int&gt; v(10);<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 建立整形向量（vector），大小为10;</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 向量是一个在标准C库中的一个模板(见条款M35) </span></p>
<p><span>v[5] = 10;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// 这个被赋值的目标对象就是操作符[]返回的值</span></p>
<p><span><span>&nbsp;&nbsp;&nbsp; </span>如果操作符[]返回一个指针，那么后一个语句就得这样写：</span></p>
<p><span>*v[5] = 10;</span></p>
<p><span>但是这样会使得<span>v看上去象是一个向量指针。因此你会选择让操作符返回一个引用。（这有一个有趣的例外，参见条款M30）</span></span></p>
<p><span>当你知道你必须指向一个对象并且不想改变其指向时，或者在重载操作符并为防止不必要的语义误解时，你不应该使用指针。而在除此之外的其他情况下，则应使用指针。<br><br>总之,引用不可以指向空值,指针可以指向空值;引用总是指向在初始化时被指定的对象，而指针可以被重新赋值以指向另一个不同的对象.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 摘自&nbsp; 林锐《高质量C++编程》<br></span></p>
</div>
<img src ="http://www.cppblog.com/susu/aggbug/21390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/susu/" target="_blank">学习才能进步</a> 2007-04-06 13:25 <a href="http://www.cppblog.com/susu/archive/2007/04/06/21390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>似水流年</title><link>http://www.cppblog.com/susu/archive/2007/03/26/20605.html</link><dc:creator>学习才能进步</dc:creator><author>学习才能进步</author><pubDate>Mon, 26 Mar 2007 05:58:00 GMT</pubDate><guid>http://www.cppblog.com/susu/archive/2007/03/26/20605.html</guid><wfw:comment>http://www.cppblog.com/susu/comments/20605.html</wfw:comment><comments>http://www.cppblog.com/susu/archive/2007/03/26/20605.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/susu/comments/commentRss/20605.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/susu/services/trackbacks/20605.html</trackback:ping><description><![CDATA[看看自己申请这个博客的时间,整整过去一年有余,而自己在C++方面却没什么进展，开个头就放弃的编程学习，让我如今的求职路举步危艰,我该如何去追悔这似水流年.从今天开始踏踏实实的去给自己充电吧,只有浮躁没有沉淀，最终将随流水漂浮一具空壳．<img src ="http://www.cppblog.com/susu/aggbug/20605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/susu/" target="_blank">学习才能进步</a> 2007-03-26 13:58 <a href="http://www.cppblog.com/susu/archive/2007/03/26/20605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏内存修改</title><link>http://www.cppblog.com/susu/archive/2006/03/16/4224.html</link><dc:creator>学习才能进步</dc:creator><author>学习才能进步</author><pubDate>Thu, 16 Mar 2006 02:07:00 GMT</pubDate><guid>http://www.cppblog.com/susu/archive/2006/03/16/4224.html</guid><wfw:comment>http://www.cppblog.com/susu/comments/4224.html</wfw:comment><comments>http://www.cppblog.com/susu/archive/2006/03/16/4224.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/susu/comments/commentRss/4224.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/susu/services/trackbacks/4224.html</trackback:ping><description><![CDATA[<P align=justify>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 昨天看了一天的《windows程序设计》,本来第三章是看过了，可是总感觉对那个线程和进程的东西理解不够深刻，于是我又回头看了一遍，今天算是理解比较深刻一点了吧，自我感觉！<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;原理就是搜索到游戏进程所在的内存地址，然后直接修改内存地址的数据，前一次看，对内存地址搜索一块，只是直接拷贝代码，没有理解，今天知道了，查找过程中需要输出的中间数据也增加了点，也理解了格式“%081X”格式指的是输出8位的16进制数，不足前面补0，我是观察输出结果如此理解，不知道有没有偏差！<BR>&nbsp;&nbsp; 另外，注意到在一个程序中打开另外进程时，路径一定不能写错，而且中间是双斜线，而不是单的，如：char szFileName[] = "E:\\VC++例子<A href="file://\\vclesson\\2\\Testor\\Debug\\Testor.exe">\\vclesson\\2\\Testor\\Debug\\Testor.exe</A>"; 如果改成单的就打不开，之前错误一直没查出来，虽然只是一点点进步，心里还是很高兴的，我将继续努力！<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <IMG alt=运行效果 hspace=0 src="C:\Documents and Settings\susu\桌面\新建 BMP 图像.bmp" align=baseline border=0>&nbsp; <BR>今天学习多线程同步和优先级的设定问题！<BR></P><img src ="http://www.cppblog.com/susu/aggbug/4224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/susu/" target="_blank">学习才能进步</a> 2006-03-16 10:07 <a href="http://www.cppblog.com/susu/archive/2006/03/16/4224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>