一,QueryInterface函数
原型:

HRESULT  __stdcall QueryInterface(const IID&iid,void **ppv);

iid:标志客户所需的接口。是”一个接口标志符“结构(IID)。
ppv:QueryInterface用来存放所请求接口的地址。

返回值:可以返回S_OK 或 E_NOINTERFACE应该用SUCEEDED或者FAILED宏验证是否成功。

使用方法:

假如知道一个指向IUnknown接口的指针pI,传给它一个接口标志符即可

例如:

void Foo(IUnknown * pI)
{
    IX 
* pIX = NULL;

    HRESULT hr 
= pI->QueryInterface(IID_IX,(void **)pIX);

    
if(SUCCEEDED(hr))
    
{
      pIX
->FX();
     }

}


//QueryInterface的实现。

HRESULT _stdcall  CA::QueryInterface(
const    IID&iid,void **ppv)
{
    
if(iid == IID_IUnknown)
    
{
      
*ppv = static_cast<IX *>(this);
    }

    
else  if(iid == IID_IX)
    
{
      
*ppv = static_cast<IX *>(this);
    }

    
else  if(iid == IID_IY)
    
{
      
*ppv = static_cast<IY *>(this);
    }

    
else  if(iid == IID_IUnknown)
    
{
      
*ppv = NULL;
      
return E_NOINTERFACE;
    }


    static_cast 
<IUnknown *> (* ppv)->AddRef();
    retru S_OK;

}



多重继承及类型转换。

通常将一种类型的指针转换为另一种类型并不会改变它的值。为了支持多重继承,某些情况下,C++必须改变类指针的值。
假如一个类定义如下:

class CA: public IX,public IY{...};

由于CA同时继承了IX,IY因此可以使用IX或IY指针的地方均可以使用指向CA的指针。

 

void foo(IX* pIX);
void bar(IY* pIY);
int main()
{
 CA
* pA = new CA;
 foo(pA);
 bar(pA);
 delete pA;
 
return 0;
}


foo需要一个指向合法的IX的虚拟函数表的指针;
bar需要一个指向合法的IY的虚拟函数表的指针;
当然IX和IY的虚拟函数表的内容是不一样的。因此将一个IX vtbl传给bar时,此函数是不能正常工作的。
因此编译器将同一指针传给foo和bar是不可能的,它必须对CA的指针进行修改以便他指向一个合适的vtbl指针。
下图显示了CA对象的内存结构。

2.jpg

Posted on 2005-11-01 16:56 艾凡赫 阅读(872) 评论(0)  编辑 收藏 引用 所属分类: COM

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理