background image

C++ 中的指针使用方法解惑

在下列函数声明中,为什么要同时使用 *和&符号?以及什么场合使用这种声明方式? 

void

 

func1(

 

MYCLASS

 

*&pBuildingElement

 

);

 

论坛中经常有人问到这样的问题。本文试图通过一些实际的指针使用经验来解释这个问

 

仔细看一下这种声明方式,确实有点让人迷惑。在某种意义上,"*"和"&"是意思相对的两
个东西,把它们放在一起有什么意义呢?。为了理解指针的这种做法,我们先复习一下
C/C++编程中无所不在的指针概念。我们都知道 MYCLASS*的意思:指向某个对象的指
针 , 此 对 象 的 类 型 为 MYCLASS

 

void   func1(MYCLASS   *pMyClass);  

//

 

 

MYCLASS*   p   =   new   MYCLASS;

 

func1(p);

 

上面这段代码的这种处理方法想必谁都用过,创建一个 MYCLASS 对象,然后将它传入
func1 函数。现在假设此函数要修改 pMyClass  

: void func1(MYCLASS *pMyClass) 

{

 

DoSomething(pMyClass);

 

pMyClass   =   //

 

 

}

 

第二条语句在函数过程中只修改了 pMyClass 的值。并没有修改调用者的变量 p 的值。如
果 p 指向某个位于地址 0x008a00 的对象,当 func1 返回时,它仍然指向这个特定的对
象 。 ( 除 非 func1 有 bug

 

将 堆 弄 乱 了 , 完 全 有 这 种 可 能 。 )

现在假设你想要在 func1 中修改 p 的值。这是你的权利。调用者传入一个指针,然后函数
给这个指针赋值。以往一般都是传双指针,即指针的指针,例如, CMyClass**。 
MYCLASS*

 

p

 

=

 

NULL;

 

func1(&p);

 

void

 

func1(MYCLASS**

 

pMyClass);

 

{

 

*pMyClass

 

=

 

new

 

MYCLASS;

 

……

 

}

 

调用 func1 之后,p 指向新的对象。在 COM 编程中,你到处都会碰到这样的用法--例如
在 查 询 对 象 接 口 的 QueryInterface

 

函 数 中 : interface   ISomeInterface   {  

HRESULT

 

QueryInterface(IID

 

&iid,

 

void**

 

ppvObj);

 

……

 

};

 

LPSOMEINTERFACE

 

p=NULL;

 

pOb->QueryInterface(IID_SOMEINTERFACE,

 

&p);