📄 [8] references, c++ faq lite.htm
字号:
src="[8] References, C++ FAQ Lite.files/new.gif"></H3></DIV><SMALL><EM>[Recently
created thanks to <A href="mailto:Robert.Cullen@fid-intl.com">Robert Cullen</A>
(on 4/01). <A
href="http://www.sunistudio.com/cppfaq/references.html#[8.7]">Click here to go
to the next FAQ in the "chain" of recent
changes<!--rawtext:[8.7]:rawtext--></A>.]</EM></SMALL>
<P>连接这些方法的调用,因此被称为<I>方法链</I>
<P>第一个被执行的是 <TT>object.method1()</TT>。它返回对象,可能是对象的引用(如,<TT>method1()</TT>可能以
<TT>return *this</TT>
结束),或可能是一些其他对象。我们姑且把返回的对象称为<TT>objectB</TT>。然后<TT>objectB</TT>成为<TT>method2()</TT>的<TT>this</TT>对象。
<P>方法链最常用的地方是<TT>iostream</TT>库。例如,<TT>cout << x << y</TT>
works because <TT>cout << x</TT>是一个返回<TT>cout</TT>.的函数
<P>虽然使用的较少,但仍然要熟练掌握的是在<A
href="http://www.sunistudio.com/cppfaq/ctors.html#[10.15]">命名参数用法(Named
Parameter Idiom)</A>中使用方法链。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/references.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/references.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/classes-and-objects.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[8.5]></A>
<DIV class=FaqTitle>
<H3>[8.5] 如何能够使一个引用重新指向另一个对象?</H3></DIV>
<P>不行。
<P>你无法让引用与其指示物分离。
<P>和指针不同,一旦引用和对象绑定,它无法再被重新指向其他对象。引用本身不是一个对象 (它没有标识; 当试图获得引用的地址时,你将的到它的指示物的地址;
记住:引用就是它的指示物)。
<P>从某种意义上来说, 引用类似 <TT>int* const p</TT> 这样的<A
href="http://www.sunistudio.com/cppfaq/const-correctness.html#[18.5]">const指针</A>(并非如
<TT>const int* p</TT> 这样的<A
href="http://www.sunistudio.com/cppfaq/const-correctness.html#[18.4]">指向常量的指针</A>)。不管有多么类似,请不要混淆引用和指针;它们完全不同。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/references.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/references.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/classes-and-objects.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[8.6]></A>
<DIV class=FaqTitle>
<H3>[8.6] 何时该使用引用, 何时该使用指针?</H3></DIV>
<P>尽可能使用引用,不得已时使用指针。
<P>当你不需要“<A
href="http://www.sunistudio.com/cppfaq/references.html#[8.5]">重新指向</A><A
href="http://www.sunistudio.com/cppfaq/references.html#[8.5]">(reseating)</A>”时,引用一般优先于指针被选用。这通常意味着引用用于类的公有接口时更有用。引用出现的典型场合是对象的表面,而指针用于对象内部。
<P>上述的例外情况是函数的参数或返回值需要一个“临界”的引用时。这时通常最好返回/获取一个指针,并使用 NULL
指针来完成这个特殊的使命。(引用应该总是对象的别名,而不是被解除引用的 NULL 指针)。
<P>注意:由于在调用者的代码处,无法提供清晰的的引用语义,所以传统的 C 程序员有时并不喜欢引用。然而,当有了一些 C++
经验后,你会很快认识到这是信息隐藏的一种形式,它是有益的而不是有害的。就如同,程序员应该针对要解决的问题写代码,而不是机器本身。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/references.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/references.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/classes-and-objects.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html">Next section</A>
]</SMALL>
<HR>
<P><A name=[8.7]></A>
<DIV class=FaqTitle>
<H3>[8.7] 什么是对象的句柄?它是指针吗?它是引用吗?它是指向指针的指针?它是什么? <IMG alt=NEW!
src="[8] References, C++ FAQ Lite.files/new.gif"></H3></DIV><SMALL><EM>[Recently
created (on 4/01). <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html#[9.3]">Click here
to go to the next FAQ in the "chain" of recent changes<!--rawtext:[9.3]:rawtext--></A>.]</EM></SMALL>
<P>句柄术语一般用来指获取另一个对象的方法——一个广义的假指针。这个术语是(故意的)含糊不清的。
<P>含糊在实际中的某些情况下是有用的。例如,在早期设计时,你可能不准备用句柄来表示。你可能不确定是否将一个简单的指针或者引用或者指向指针的指针或者指向引用的指针或者整型标识符放在一个数组或者字符串(或其它键)以便能够以哈希表(hash-table)(或其他数据结构)或数据库键或者一些其它的技巧来查询。如果你只知道你会需要一些唯一标识的东西来获取对象,那么这些东西就被称为句柄。
<P>因此,如果你的最终目标是要让代码唯一的标识/查询一个Fred类的指定的对象的话,你需要传递一个Fred句柄这些代码。句柄可以是一个能被作为众所周知的查询表中的键(key)来使用的字符串(比如,在<A
href="http://www.sunistudio.com/cppfaq/containers-and-templates.html#[31.2]"><TT>std::map<std::string,Fred></TT>
或 <TT>std::map<std::string,Fred*></TT></A>中的键),或者它可以是一个作为数组中的索引的整数(比如,<A
href="http://www.sunistudio.com/cppfaq/freestore-mgmt.html#[16.10]"><TT>Fred* array = new Fred[maxNumFreds]</TT></A>),或者它可以是一个简单的
Fred*,或者它可以是其它的一些东西。<BR>
<P>初学者常常考虑指针,但实际上使用未初始化的指针有底层的风险。例如,如果Fred对象需要移动怎么办?当Fred对象可以被安全删除时我们如何获知?如果Fred对象需要(临时的)连续的从磁盘获得怎么办?等等。这些时候的大多数,我们增加一个间接层来管理位置。例如,句柄可以是Fred**,指向Fred*的指针可以保证不会被移动。当Fred对象需要移动时,你只要更新指向Fred*的指针就可以了。或者让用一个整数作为句柄,然后在表或数组或其他地方查询Fred的对象(或者指向Fred对象的指针)。<BR>
<P>重点是当我们不知道要做的事情的细节时,使用句柄。
<P>使用句柄的另一个时机是想要将已经完成的东西含糊化的时候(有时用术语magic cookie也一样,就像这样,“软件传递一个magic
cookie来唯一标识并定位适当的Fred对象”)。将已经完成的东西含糊化的原因是使得句柄的特殊细节或表示物改变时所产生的连锁反应最小化。举例来说,当将一个句柄从用来在表中查询的字符串变为在数组中查询的整数时,我们可不想更新大量的代码。
<P>当句柄的细节或表示物改变时,维护工作更为简单(或者说阅读和书写代码更容易),因此常常将句柄封装到类中。这样的类常<A
href="http://www.sunistudio.com/cppfaq/operator-overloading.html">重载<TT>operator-></TT>
和 <TT>operator*</TT>算符<!--rawtext:[13]:rawtext--></A>(既然句柄的效果象指针,那么它可能卡起来也象指针)。
<P><SMALL>[ <A
href="http://www.sunistudio.com/cppfaq/references.html#top">Top</A> | <A
href="http://www.sunistudio.com/cppfaq/references.html#bottom">Bottom</A>
| <A
href="http://www.sunistudio.com/cppfaq/classes-and-objects.html">Previous section</A>
| <A
href="http://www.sunistudio.com/cppfaq/inline-functions.html">Next section</A>
]</SMALL>
<HR>
<P><A name=bottom></A><A href="mailto:cline@parashift.com"><IMG height=26
alt=E-Mail src="[8] References, C++ FAQ Lite.files/mbox.gif"
width=89> E-mail the author</A><BR>[ <A
href="http://www.sunistudio.com/cppfaq/index.html"><EM>C++ FAQ Lite</EM></A>
| <A
href="http://www.sunistudio.com/cppfaq/index.html#table-of-contents">Table of contents</A>
| <A
href="http://www.sunistudio.com/cppfaq/subject-index.html">Subject index</A>
| <A
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.1]">About the author</A>
| <A
href="http://www.sunistudio.com/cppfaq/copy-permissions.html#[1.2]">©</A>
| <A
href="http://www.sunistudio.com/cppfaq/on-line-availability.html#[2.2]">Download your own copy</A> ]<BR><SMALL>Revised
Apr 8, 2001</SMALL> </P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -