Тут возникла не столько проблема, сколько неудобство: при использовании нескольких интерфейсов, имеющих одинаковые описания функций, для одного и того же компонента приходится извращаться в переопределении их описаний:
interface IX
{
virtual void SetThis(int this) = 0;
};
Здравствуйте The Lex, вы писали:
TL>Тут возникла не столько проблема, сколько неудобство: при использовании нескольких интерфейсов, имеющих одинаковые описания функций, для одного и того же компонента приходится извращаться в переопределении их описаний:
TL>interface IX TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>interface IY TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>class CComp : public IX, public IY TL>{ TL> virtual void SetThis(int this); TL> // Хм... TL>};
TL>Нет ли каких предложений на эту тему? TL>Заранее благодарен...
Я решал эту проблему так, когда она возникала:
class IXImpl : public IX
{
virtual void X_SetThis(int this) = 0;
virtual void SetThis(int this)
{ X_SetThis(this); }
};
class IYImpl : public IY
{
virtual void Y_SetThis(int this) = 0;
virtual void SetThis(int this)
{ Y_SetThis(this); }
};
class CComp : public IXImpl, public IYImpl
{
virtual void X_SetThis(int this);
virtual void Y_SetThis(int this);
// Хм...
};
Здравствуйте The Lex, вы писали:
TL>Тут возникла не столько проблема, сколько неудобство: при использовании нескольких интерфейсов, имеющих одинаковые описания функций, для одного и того же компонента приходится извращаться в переопределении их описаний:
TL>interface IX TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>interface IY TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>class CComp : public IX, public IY TL>{ TL> virtual void SetThis(int this); TL> // Хм... TL>};
TL>Нет ли каких предложений на эту тему? TL>Заранее благодарен...
Может быть вам будет удобнее использовать реализацию интерфейсов в виде вложенных классов и макрос METHOD_PROLOGUE, как это используется при создании COM-интерфейсов средствами MFC. А вообще-то СОМ-сервера "ручками" писать неудобно, лучше использовать тот же MFC или ATL...
Здравствуйте The Lex, вы писали:
TL>Тут возникла не столько проблема, сколько неудобство: при использовании нескольких интерфейсов, имеющих одинаковые описания функций, для одного и того же компонента приходится извращаться в переопределении их описаний:
TL>Нет ли каких предложений на эту тему? TL>Заранее благодарен...
Могу кинуть примеры из Трельсена, где разбирается эта ситуация. А то сам книжку поищи —
Трельсен "Модель COM и применение ATL 3.0"
Твой пример не совсем корректен (или даже совсем не корректен). По теории COM, если вы получаете какой-то интерфейс от объекта, реализующего несколько интерфейсов, то по этому указателю можно запросить все остальные интерфейсы, реализуемые объектом. А как в вашем примере класс IX_Impl реализует QueryInterface(), чтобы вернуть интерфейс IY ? В данном случае это невозможно, поэтому-то в MFC-шной реализации и используются вложеннные классы, что-то типа:
class CComp : public IX_Impl, public IY_Impl
{
class IX_Impl : public IX
{
void SetThis(int this){ реализация IX } ;
Твой пример не совсем корректен (или даже совсем не корректен). По теории COM, если вы получаете какой-то интерфейс от объекта, реализующего несколько интерфейсов, то по этому указателю можно запросить все остальные интерфейсы, реализуемые объектом. А как в вашем примере класс IX_Impl реализует QueryInterface(), чтобы вернуть интерфейс IY ? В данном случае это невозможно, поэтому-то в MFC-шной реализации и используются вложеннные классы, что-то типа:
class CComp : public IX_Impl, public IY_Impl
{
class IX_Impl : public IX
{
void SetThis(int this){ реализация IX } ;
Здравствуйте sanyvaa, вы писали:
S>Может быть вам будет удобнее использовать реализацию интерфейсов в виде вложенных классов и макрос METHOD_PROLOGUE, как это используется при создании COM-интерфейсов средствами MFC. А вообще-то СОМ-сервера "ручками" писать неудобно, лучше использовать тот же MFC или ATL...
По-поводу того, что "ручками писать неудобно" у меня есть свое мнение: понимание сути процесса ведет к использованию средств, облегчающих разработку. Для использование дополнительных средств разработки (MFC, ATL) необходимо понимание как сути "нижнего уровня", так и "надстройки". При этом методы как "нижнего", так и "верхнего" уровней могут быть использованы в других случаях довольно эффективно. Но для этого их необходимо понимать.
Меня интересует именно "нижний уровень" — чистые языковые средства.
ATL — это, наверно хорошо. Но в данном случае Ваш вариант не подходит, так как реализации SetThis(...) должны находиться именно в CComp — в классе компонента.
S>Твой пример не совсем корректен (или даже совсем не корректен). По теории COM, если вы получаете какой-то интерфейс от объекта, реализующего несколько интерфейсов, то по этому указателю можно запросить все остальные интерфейсы, реализуемые объектом. А как в вашем примере класс IX_Impl реализует QueryInterface(), чтобы вернуть интерфейс IY ? В данном случае это невозможно, поэтому-то в MFC-шной реализации и используются вложеннные классы, что-то типа:
Ну, я бы сказал не полный. Что мне здесь полный код QI во всех классах прописывать?
Если юзать ATL, то проблем не возникает потому, как IUnknown реализуется один раз для всех классов. Так что чем велосипед изобретать лучше берите ATL и смотрите как IDispatchIml<> реализован.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
S>Так как в случае вложенного класса можно без проблем получить указатель pThis на внешний класс и переслать ему вызовы QueryInterface().
Тоже мне проблема this суперкласса получить. Есть много способов это сделать. ATL-щики, те вообще тип конечного суперкласса как темплэйтный параметр передают и потом делают так:
T * pT = (T*)this; pT->SomeSuperCall();
При этом и указатель на this супера не нужен.
Так что повторюсь... чем велосипеды изобретать, лучше изучать код профи (ATL на пример). А лучший способ обучения реализация своих идей их средствами и дотошное (с применением отладчика) сканирование их кода.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подходит, но имплы надо объявить как тэмплэйты. С ATL это делается за пару секунд. Подробнее смотри второй ответ sanyvaa-у и IDispatchImpl<>. Лично у нас каким макаром горы кода написано и все работает.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте Odissey, вы писали:
O>Могу кинуть примеры из Трельсена, где разбирается эта ситуация. А то сам книжку поищи — O>Трельсен "Модель COM и применение ATL 3.0"
Кинь. А то из головы описывать сложновато. Я чувствую народ не прочувствовал ;).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте VladD2, вы писали:
VD>Здравствуйте Odissey, вы писали:
O>>Могу кинуть примеры из Трельсена, где разбирается эта ситуация. А то сам книжку поищи — O>>Трельсен "Модель COM и применение ATL 3.0"
VD>Кинь. А то из головы описывать сложновато. Я чувствую народ не прочувствовал ;).
в этом примере метод Draw() есть и в IDraw и в I3DRender
это *.h
class Co3DHexagon : public IDraw
{
public:
Co3DHexagon();
virtual ~Co3DHexagon();
Здравствуйте The Lex, вы писали:
TL>Тут возникла не столько проблема, сколько неудобство: при использовании нескольких интерфейсов, имеющих одинаковые описания функций, для одного и того же компонента приходится извращаться в переопределении их описаний:
TL>interface IX TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>interface IY TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>class CComp : public IX, public IY TL>{ TL> virtual void SetThis(int this); TL> // Хм... TL>};
TL>Нет ли каких предложений на эту тему? TL>Заранее благодарен...
а не проще ли
class CIX : public IX
{
virtual void SetThis(int this){...};
};
class CIY : public IY
{
virtual void SetThis(int this){...};
};
Здравствуйте The Lex, вы писали:
TL>Тут возникла не столько проблема, сколько неудобство: при использовании нескольких интерфейсов, имеющих одинаковые описания функций, для одного и того же компонента приходится извращаться в переопределении их описаний:
TL>interface IX TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>interface IY TL>{ TL> virtual void SetThis(int this) = 0; TL>};
TL>class CComp : public IX, public IY TL>{ TL> virtual void SetThis(int this); TL> // Хм... TL>};
TL>Нет ли каких предложений на эту тему? TL>Заранее благодарен...
а не проще ли:
class CIX : public IX
{
virtual void SetThis(int this){...};
};
class CIY : public IY
{
virtual void SetThis(int this){...};
};