ручное переопределение таблицы виртуальных функций
От: Аноним  
Дата: 27.05.01 11:48
Оценка:
Хай Алл !

Тут ситуация возникла -- самое простое решение на мой взгляд будет переопределение таблицы виртуальных функций класса.
Ситуация такова:
есть, скажем, указатель на интерфейс IXMLDOMNode, полученный из вызова опять же метода другого интерфейса.
Интерфейс не маленький -- 36 методов самого интерфейса, плюс 4 метода IDispatch, плюс 3 метода IUnknown.
Задача -- создать объект-прокси для этого интерфейса, который в конструкторе будет делать что-то, и в деструкторе опять же делать что-то (вызывая методы полученного интерфейса), а в остальном служить просто как прокси к полученному интерфейсу.

Стандартными способами С++ это выгладит примерно так:

class CVXMLDOMNodeProxy
: public IXMLDOMNode,
public CRefCounter
{
public:
CVXMLDOMNodeProxy (IXMLDOMNode *pNode, bool bInternalLock);
virtual ~CVXMLDOMNodeProxy ();

public:
//** IUnknown methods
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, LPVOID *ppv);
virtual ULONG STDMETHODCALLTYPE AddRef () { return CRefCounter::AddRef(); };
virtual ULONG STDMETHODCALLTYPE Release () { return CRefCounter::Release(); };
//** IDispatch methods
//........
//** IXMLDOMNode methods
//.........

protected:
bool InternalLock ();
bool InternalUnlock ();

protected:
IXMLDOMNode *m_pNode;
bool m_bInternalLocked;
};

CVXMLDOMNodeProxy::CVXMLDOMNodeProxy (IXMLDOMNode *pNode, bool bInternalLock)
{
if (m_pNode = pNode) {
m_pNode->AddRef();
};
if (bInternalLock) {
InternalLock();
};
};
CVXMLDOMNodeProxy::~CVXMLDOMNodeProxy ()
{
if (m_bInternalLocked) {
InternalUnlock();
};
if (m_pNode) {
m_pNode->Release();
m_pNode = NULL;
};
};

далее идут методы IDispatch и IXMLDOMNode, передающие управление соответствующим методам объекта m_pNode

============================================
Внимание вопрос:
КАК можно избежать повторения всех методов наследуемых интерфейсов в теле класса?
Т.е выход я вижу такой -- создать где-либо в памяти структурку с указателями на действительные члены полученного интерфейса, в кострукторе объекта-прокси её инициализировать правильно, и вернуть её в качестве указателя на исходный интерфейс.
Сам объект-прокси будет пронаследован только от IUnknown, и указатели в таблице будут показывать на ЕГО методы IUnknown, в остальном же будут повторять структуру исходного интерфейса.

Кто-нибудь владеет информацией о формате таблицы виртуальных функций -- по моему это в Страуструпе должно быть.
К сожалению сам я не имею под рукой этого издания, а разбираться с дизассемблированием С++ кода времени нет.
Буду очень благодарен за помощь.

CU
-- vano@qdamage
Re: ручное переопределение таблицы виртуальных функций
От: Varchev ILYA Nickolaevich  
Дата: 28.05.01 16:48
Оценка:
А>============================================
А>Внимание вопрос:
А>КАК можно избежать повторения всех методов наследуемых интерфейсов в теле класса?
А>Т.е выход я вижу такой -- создать где-либо в памяти структурку с указателями на действительные члены полученного интерфейса, в кострукторе объекта-прокси её инициализировать правильно, и вернуть её в качестве указателя на исходный интерфейс.
А>Сам объект-прокси будет пронаследован только от IUnknown, и указатели в таблице будут показывать на ЕГО методы IUnknown, в остальном же будут повторять структуру исходного интерфейса.

А>Кто-нибудь владеет информацией о формате таблицы виртуальных функций -- по моему это в Страуструпе должно быть.

А>К сожалению сам я не имею под рукой этого издания, а разбираться с дизассемблированием С++ кода времени нет.
А>Буду очень благодарен за помощь.

А>CU

А>-- vano@qdamage


может поможет переопределение "operator ->" ?
Re: ручное переопределение таблицы виртуальных функций
От: IT Россия linq2db.com
Дата: 29.05.01 12:00
Оценка:
А>Тут ситуация возникла -- самое простое решение на мой взгляд будет переопределение таблицы виртуальных функций класса.

Хак в чимтом виде. Как насчёт агрегации? Да и ваще, можно ли узнать конечную цель, может обойдёмся штатными средствами?
Если нам не помогут, то мы тоже никого не пощадим.
Re: ручное переопределение таблицы виртуальных функций
От: IAZ http://iaz.simb.ru
Дата: 29.05.01 19:45
Оценка:
Можно воспользоваться шаблонным классом CComQIPtr.
Например вот так:

typedef CComQIPtr<IXMLDOMNode> IXML;
class CVXMLDOMNodeProxy : public IXML, public CRefCounter
{
public:
CVXMLDOMNodeProxy(IXMLDOMNode* pXML, bool bInternalLock) : IXML(pXML)
{
// все что угодно
}
virtual ~CVXMLDOMNodeProxy ()
{
}
....
};

Доступ к методам класса CVXMLDOMNodeProxy происходит через operator.()
а к методам интерфейса IXMLDOMNode через operator->()
Кто ищет то всегда найдет!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.