class IUnknown
{
public:
virtual int QueryInterface(char*IName,void**ppv)=0;//查询接口
virtual void Release()=0; //释放接口
};
class IA:public IUnknown
{
public:
virtual void f1()=0;
virtual void f2()=0;
};
class IB:public IUnknown
{
public:
virtual void g1()=0;
virtual void g2()=0;
};
class A:public IA,IB
{
private:
char*s1,*s2,*s3,*s4;
public:
A()
{
s1="This is f1()";
s2="This is f2()";
s3="This is g1()";
s4="This is g2()";
}
virtual void f1(){cout<<s1<<endl;}
virtual void f2(){cout<<s2<<endl;}
virtual void g1(){cout<<s3<<endl;}
virtual void g2(){cout<<s4<<endl;}
virtual int QueryInterface(char*IName,void**ppv)
{
if(IName=="IA") {*ppv = (IA*)(this);return 1;}
else if(IName=="IB"){*ppv = (IB*)(this);return 1;}
else return 0;
}
virtual void Release(){delete this;}
};
A*GreateInst()
{
return new A;
}
void CoGetInst(char*IName,void**ppv)
{
A*a=GreateInst();
a->QueryInterface(IName,ppv);
}
void main()
{
IA*pIA;
CoGetInst("IA",(void**)&pIA);
pIA->f1();
IB*pIB;
pIA->QueryInterface("IB",(void**)&pIB);
pIB->g2();
pIA->Release();
}
一个很好的实例是关于ArcGIS二次开发的实例:
IMap pMap = axMapControl1.Map;
IActiveView pActiveView = pMap as IActiveView;
IGraphicsContainer pGraphicsContainer = pMap as IGraphicsContainer;
Map类实现了IMap、IActiveView、IGraphicsContainer等等这几个接口;
在这里的A类就相当于Map类,在主函数中(即相当于客户端,完全屏蔽掉了类A),直接调用了A所接口。
这就是所谓COM组件中接口的机制。