一般情况下我们不使用指向指针的指针,因为这带来了操作的复杂性。但有些情况下我们不得不用。当指针作为一个函数的参数输出时,它的作用就显示出来了。
例如:设计一个函数:void fun1(char sz[], char search, char * pa)
实现代码如下:
void fun1(char sz[], char search, char* pa)
{
for (int i=0;*(sz+i)!=0;i++)
{
if (*(sz+i)==search)
{
pa=sz+i;
break;
}
else if (*(sz+i)==0)
{
pa=0;
break;
}
}
}
int main(int argc, char* argv[])
{
char str[]={"afsdfsdfdf/0"};
char a='d';
char *p=0;
fun1(str,a,p);
if (0==p)
{
printf("没找到!/n");
}
else
{
printf("找到了,p=%d",p);
}
return 0;
}
令人奇怪的是:输出的结果为—-没找到。为什么没找到呢?
问题出在:参数传递时。
函数调用时会对每一个参数进行一个隐含的赋值操作。
如:sz = str;
Search = a;
Pa = p; //以上三句是调用时隐含的动作。
……
修改后:
void fun2(char sz[], char search, char** ppa)
{
for (int i=0;*(sz+i)!=0;i++)
{
if (*(sz+i)==search)
{
*ppa=sz+i;
break;
}
else if (*(sz+i)==0)
{
*ppa=0;
break;
}
}
}
int main(int argc, char* argv[])
{
char str[]={"afsdfsdfdf/0"};
char a='d';
char *p=0;
fun2(str,a,&p);
if (0==p )
{
printf("没找到!/n");
}
else
{
printf("找到了,p=%d",p);
}
return 0;
}
这时调用函数时的操作变成如下:
sz=str;
search=a;
ppa=&p; //以上三句是调用时隐含的动作。
……
对*ppa的修改就是对p值的修改。
再举个例子:
void GetMemory(char* p)
{
p = "bbb";
}
int main(int argc, char* argv[])
{
char *v = "aaa";
GetMemory(v);
cout<< v <<endl;
return 0;
}
我们发现输出的结果仍然是aaa。
对它进行修改:
void GetMemory(char** p)
{
*p = "bbb";
}
int main(int argc, char* argv[])
{
char *v = "aaa";
GetMemory(&v);
cout<< v <<endl;
return 0;
}
此时输出的结果为bbb.
所以我们经常会在COM里面看到双重指针的使用。比如QueryInterface来获取指针,指针ppv通过函数的一个参数的形式向外输出。就是这个原因。
STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
if( riid == IID_IBird || riid == IID_IUnknown )
*ppv = static_cast<IBird*>(this);
else if( riid == IID_ISnappyDresser )
*ppv = static_cast<ISnappyDresser*>(this);
else *ppv = 0;
if( *ppv ) {
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
CopyFrom: