此 处 , p 是 SOMEINTERFACE 类 型 的 指 针 , 所 以 &p 便 是 指 针 的 指 针 , 在
QueryInterface 返回的时候,如果调用成功,则变量 p
包含一个指向新的接口的指针。
如果你理解指针的指针,那么你肯定就理解指针引用,因为它们完全是一回事。如果你象
下
面
这
样
声
明
函
数
:
void
func1(MYCLASS
*&pMyClass);
{
pMyClass
=
new
MYCLASS;
……
}
其实,它和前面所讲得指针的指针例子是一码事,只是语法有所不同。传递的时候不用传
p
的
地
址
&p
,
而
是
直
接
传
p
本
身
:
MYCLASS*
p
=
NULL;
func1(p);
在调用之后,p 指向一个新的对象。一般来讲,引用的原理或多或少就象一个指针,从语
法上看它就是一个普通变量。所以只要你碰到*&,就应该想到**。也就是说这个函数修改
或可能修改调用者的指针,而调用者象普通变量一样传递这个指针,不使用地址操作符
&
。
至于说什么场合要使用这种方 法 ,我会说,极少。MFC 在其集合类中用到了它--例如,
CObList , 它 是 一 个 CObjects
指 针 列 表 。 class CObList : public CObject {
……
//
获
取
/
修
改
指
定
位
置
的
元
素
CObject*&
GetAt(POSITION
position);
CObject*
GetAt(POSITION
position)
const;
};
这 里 有 两 个 GetAt
函 数 , 功 能 都 是 获 取 给 定 位 置 的 元 素 。 区 别 何 在 呢 ?
区别在于一个让你修改列表中的对象,另一个则不行。所以如果你写成下面这样:
CObject*
pObj
=
mylist.GetAt(pos);
则 pObj 是 列 表 中 某 个 对 象 的 指 针 , 如 果 接 着 改 变 pObj
的 值 : pObj =
pSomeOtherObj;
这并改变不了在位置 pos 处的对象地址,而仅仅是改变了变量 pObj。但是,如果你写成
下
面
这
样
:
CObject*& rpObj = mylist.GetAt(pos);
现在,rpObj 是引用一个列表中的对象的指针,所以当改变 rpObj 时,也会改变列表中
位置 pos 处的对象地址--换句话说,替代了这个对象。这就是为什么 CObList 会有两个
GetAt 函数的缘故。一个可以修改指针的值,另一个则不能。注意我在此说的是指针,不
是 对 象 本 身 。 这 两 个 函 数 都 可 以 修 改 对 象 , 但 只 有 *&
版 本 可 以 替 代 对 象 。