background image

此 处 , 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 函数的缘故。一个可以修改指针的值,另一个则不能。注意我在此说的是指针,不
是 对 象 本 身 。 这 两 个 函 数 都 可 以 修 改 对 象 , 但 只 有 *&

 

版 本 可 以 替 代 对 象 。