//想知道一个类实现多个接口,而这些接口中定义了相同的成员函数会发生什么情况
//答案是能查询到多个接口,却只能实现同一个功能
//要是查询不同接口而实现不同功能,该怎么办呢?我还没想到。
#include <objbase.h>
#include <iostream>
using namespace std;
static GUID IID_ISimpleMath;
static GUID IID_IAdvancedMath;
interface ISimpleMath : public IUnknown
{
public:
virtual int Add(int nOp1, int nOp2) = 0;
virtual int Subtract(int nOp1, int nOp2) = 0;
virtual int Multiply(int nOp1, int nOp2) = 0;
virtual int Divide(int nOp1, int nOp2) = 0;
};
interface IAdvancedMath : public IUnknown
{
public:
virtual int Add(int nOp1, int nOp2) = 0;/*这个成员函数在interface ISimpleMath中也有定义*/
virtual int Factorial(int nOp1) = 0;
virtual int Fabonacci(int nOp1) = 0;
};
class CMath : public ISimpleMath,public IAdvancedMath
{
private:
ULONG m_cRef;
public:
CMath()
{ m_cRef=0;
};
//IUnknown Method
STDMETHOD(QueryInterface)(REFIID riid, void **ppv)
{// 这里这是实现dynamic_cast的功能,但由于dynamic_cast与编译器相关。
if(riid == IID_ISimpleMath)
*ppv = static_cast<ISimpleMath *>(this);
else if(riid == IID_IAdvancedMath)
*ppv = static_cast<IAdvancedMath *>(this);
else if(riid == IID_IUnknown)
*ppv = static_cast<ISimpleMath *>(this);
else {
*ppv = 0;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef(); //这里要这样是因为引用计数是针对组件的
return S_OK;
};
STDMETHOD_(ULONG, AddRef)()
{ return ++m_cRef;
};
STDMETHOD_(ULONG, Release)()
{ ULONG res = --m_cRef; // 使用临时变量把修改后的引用计数值缓存起来
if(res == 0) // 因为在对象已经销毁后再引用这个对象的数据将是非法的
delete this;
return res;
};
// ISimpleMath Method
int Add(int nOp1, int nOp2)
{ return nOp1+nOp2;
};//这个也是IAdvancedMath Method?
int Subtract(int nOp1, int nOp2)
{ return nOp1-nOp2;
};
int Multiply(int nOp1, int nOp2)
{ return nOp1*nOp2;
};
int Divide(int nOp1, int nOp2)
{ if(!nOp2) throw("除数为零");
return nOp1/nOp2;
};
// IAdvancedMath Method
int Factorial(int nOp)
{ if(nOp <= 1)
return 1;
return nOp * Factorial(nOp - 1);
};
int Fabonacci(int nOp)
{ if(nOp <= 1)
return 1;
return Fabonacci(nOp - 1) + Fabonacci(nOp - 2);
};
};
int main()
{ CoCreateGuid(&IID_ISimpleMath);
CoCreateGuid(&IID_IAdvancedMath);
ISimpleMath *pSimpleMath = NULL; // 声明接口指针
IAdvancedMath *pAdvMath = NULL;
CMath *pMath = new CMath; // 创建对象实例,我们暂时这样创建对象实例,COM有创建对象实例的机制
HRESULT hr;
hr=pMath->QueryInterface(IID_ISimpleMath, (void **)&pSimpleMath); // 查询对象实现的接口ISimpleMath
if(!pSimpleMath) return hr;
cout << "10 + 4 = " << pSimpleMath->Add(10, 4) << endl;
pSimpleMath->QueryInterface(IID_IAdvancedMath, (void **)&pAdvMath); // 查询对象实现的接口IAdvancedMath
if(!pAdvMath) return hr;
cout << "10 + 4 = " << pAdvMath->Add(10, 4) << endl;//
cout << "10 Fabonacci is " << pAdvMath->Fabonacci(10) << endl;
pAdvMath->Release();
pSimpleMath->Release();
return 0;
}