Доброго времени суток.
Несколько классов наследуются от IUnknown:
#include <objbase.h>
// pure abstract base class
interface IX : IUnknown{
virtual void __stdcall Fx() = 0; // pure virtual function
};
// pure abstract base class
interface IY : IUnknown{
virtual void __stdcall Fy() = 0; // pure virtual function
};
// pure abstract base class
interface IZ : IUnknown{
virtual void __stdcall Fz() = 0; // pure virtual function
};
extern "C"{
extern const IID IID_IX;
extern const IID IID_IY;
extern const IID IID_IZ;
}
Эти интерфейсы я реализую в классе CA (см. код ниже).
Интерфейс IUnknown определяет три функции: QueryInterface, AddRef и Release. Мне нужно, чтобы реализация функции QueryInterface была общей для всех трёх интерфейсов (это успешно работает), а вот функции AddRef и Release должны быть определены индивидуально для каждого интерфейса (с этим как раз таки проблема).
Т.е. если переменная объявлена как IX, то для неё должны использоваться AddRef и Release именно те, которые я хочу определить для IX. Та же история по отношению и к IY, IZ. Это позволит мне вести подсчёт ссылок на компонент для каждого интерфейса (для удобства в отладке). Но синтаксис, который я записал - неверный (см. TODO в комментариях). Как это сделать правильно?
Текущий вариант кода класса CA такой:
//#include "../../std_lib_facilities.h"
#include <iostream>
#include "IFace.h"
// COM component
class CA :
public IX,
public IY,
public IZ
{
public:
CA();
~CA();
virtual void __stdcall Fx(); // IX
virtual void __stdcall Fy(); // IY
virtual void __stdcall Fz(); // IZ
// IUnknown
virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
virtual ULONG __stdcall IX::AddRef(); // for IX instances
virtual ULONG __stdcall IX::Release(); // for IX instances
virtual ULONG __stdcall IY::AddRef(); // for IY instances
virtual ULONG __stdcall IY::Release(); // for IY instances
virtual ULONG __stdcall IZ::AddRef(); // for IZ instances
virtual ULONG __stdcall IZ::Release(); // for IZ instances
private:
// Each interface has own counter (for convenience of debugging)
ULONG ix_counter;
ULONG iy_counter;
ULONG iz_counter;
};
CA::CA() :
ix_counter(0),
iy_counter(0),
iz_counter(0){
std::cout << "CA:CA()" << std::endl;
}
CA::~CA(){
std::cout << "CA:~CA()" << std::endl;
}
// TODO: this is wrong syntax (function signature)
ULONG __stdcall CA::IX::Release(){
InterlockedDecrement(&ix_counter);
ULONG count = ix_counter + iy_counter + iz_counter;
if (0 == count) delete this;
return count;
}
void __stdcall CA::Fx(){ std::cout << "\tFx()" << std::endl; }
void __stdcall CA::Fy(){ std::cout << "\tFy()" << std::endl; }
void __stdcall CA::Fz(){ std::cout << "\tFz()" << std::endl; }
// This is function is the same for each interface
HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv){
HRESULT h = S_OK;
if (IID_IX == iid){
*ppv = static_cast<IX*>(this);
std::cout << "QueryInterface: IX interface returned." << std::endl;
}
else if (IID_IY == iid){
*ppv = static_cast<IY*>(this);
std::cout << "QueryInterface: IY interface returned." << std::endl;
}
else if (IID_IZ == iid){
*ppv = static_cast<IZ*>(this);
std::cout << "QueryInterface: IZ interface returned." << std::endl;
}
else{
std::cout << "QueryInterface: Unexpected interface. NULL returned."
<< std::endl;
h = E_NOINTERFACE;
*ppv = NULL;
}
return h;
}
// TODO: this is wrong syntax (function signature)
ULONG __stdcall CA::IX::AddRef(){
return InterlockedIncrement(&ix_counter);
}
Спасибо