Решился и я приобщиться к высоким материям и немного отпозти от Delphi к VC и ATL и тут же приполз
Итак:
Есть интерфейс IBase: IDispatch.
От него есть наследник IMyInterface.
(ПРИМЕЧАНИЕ: В моем случае чисто IBase не используется, а используются только его наследники)
Соответствено есть класс реализующий
IBase- CBase: public IBase
теперь в классе реализующем IMyInterface мне хочется написать
CMyInterface: public IMyInterface, CBase
дабы не реализовывать методы из IBase
но! вот тут-то и начинается самое интересное Эта хитрая скотинка VC заявляет, мол не могу пронаследовать один класс с аттрибутом coclass от другого с аттрибутом coclass.
Абыдо, да ? Ладно (см. примечание), удаляем атрибуты coclass, etc- перестает ругаться на невозможность наследования, начинает ругаться на то, что не может привести _ComMapClass к IMyInterface (или к IBase я точно не помню, у меня щаз под рукой VC нет.)
Ладно, думаю, помню как в VC6 боролся: пишу com_interface_entry("COM_INTERFACE_ENTRY2(IBase, IMyInterface)"), все равно не лечит!
Тут уж я совсем обиделся Ладно, из "CBase: public IBase" удаляю ": public IBase", т.е. остается просто CBase и методы от IBase. Теперь оно ругается на то что в CMyInterface не реализованы методы IBase, хотя они есть в CBase
Причем в VC6 мне удавалось добиться того чего я хочу, путем COM_INTERFACE_ENTRY2, но в VC7 примерчик который чудно работал в VC6 не собирается и так-же ругается
Просвятите, pls, как с этим бороться (блин, в делфях все так просто и понятно )
Здравствуйте SDM, Вы писали:
SDM>Решился и я приобщиться к высоким материям и немного отпозти от Delphi к VC и ATL и тут же приполз
[skipped] SDM>Просвятите, pls, как с этим бороться (блин, в делфях все так просто и понятно
Посмотри как реализуется IDispatchImpl<T> от базового интерфейса T : IDispatch. Он реализует методы базового интерфейса IDispatch. Здесь аналогия: IDispatch — это твой IBase, а T — IMyInterface.
Точно так же и ты можешь сделать IBaseImpl<T> с реализацией методов IBase и использовать IBaseImpl<IBase> и IBaseImpl<IMyInterface> и т.п. там, где нужно.
Здравствуйте Vi2, Вы писали:
Vi2>Посмотри как реализуется IDispatchImpl<T> от базового интерфейса T : IDispatch. Он реализует методы базового интерфейса IDispatch. Здесь аналогия: IDispatch — это твой IBase, а T — IMyInterface.
Vi2>Точно так же и ты можешь сделать IBaseImpl<T> с реализацией методов IBase и использовать IBaseImpl<IBase> и IBaseImpl<IMyInterface> и т.п. там, где нужно.
Класс! Похоже это то что надо! Но остается риторический вопрос: Получается что через наследование нельзя? И еще, а как оно развернется компилятором: создаст мне N реализаций одного и того же IBaseImpl или всетаки сделает одну?
Здравствуйте SDM, Вы писали:
SDM>Здравствуйте Vi2, Вы писали:
Vi2>>Посмотри как реализуется IDispatchImpl<T> от базового интерфейса T : IDispatch. Он реализует методы базового интерфейса IDispatch. Здесь аналогия: IDispatch — это твой IBase, а T — IMyInterface.
Vi2>>Точно так же и ты можешь сделать IBaseImpl<T> с реализацией методов IBase и использовать IBaseImpl<IBase> и IBaseImpl<IMyInterface> и т.п. там, где нужно.
SDM>Класс! Похоже это то что надо! Но остается риторический вопрос: Получается что через наследование нельзя? И еще, а как оно развернется компилятором: создаст мне N реализаций одного и того же IBaseImpl или всетаки сделает одну?
1. через наследование нельзя — нельзя наследовать реализации интерфейсов.
2. компилятор создаст N реализаций твоего интерфейса (как и всегда при работе с шаблонами).
Konstantin Trunin http://blog.trunin.com — эффективное управление людьми, проектами, собой
Здравствуйте Joker3D, Вы писали:
Vi2>>>Точно так же и ты можешь сделать IBaseImpl<T> с реализацией методов IBase и использовать IBaseImpl<IBase> и IBaseImpl<IMyInterface> и т.п. там, где нужно.
SDM>>Класс! Похоже это то что надо! Но остается риторический вопрос: Получается что через наследование нельзя? И еще, а как оно развернется компилятором: создаст мне N реализаций одного и того же IBaseImpl или всетаки сделает одну?
JD>1. через наследование нельзя — нельзя наследовать реализации интерфейсов.
Плёхо. А кто-нибудь мне может объяснить почему? И почему в Delphi это можно сделать?
JD>2. компилятор создаст N реализаций твоего интерфейса (как и всегда при работе с шаблонами).
Совсем плохо...У меня таких классов-потомков будет вагон и маленькая тележка...
Здравствуйте SDM, Вы писали:
Vi2>>Посмотри как реализуется IDispatchImpl<T> от базового интерфейса T : IDispatch. Он реализует методы базового интерфейса IDispatch. Здесь аналогия: IDispatch — это твой IBase, а T — IMyInterface.
Vi2>>Точно так же и ты можешь сделать IBaseImpl<T> с реализацией методов IBase и использовать IBaseImpl<IBase> и IBaseImpl<IMyInterface> и т.п. там, где нужно.
SDM>Но остается риторический вопрос: Получается что через наследование нельзя?
Ну почему нельзя? Можно, но муторно и не сопровождаемо.
У тебя все структуры IBase и все IMyInterface-ы определены в h-файле от MIDLа, и соотношение между ними установлены. Вклиниться туда нет возможности без потери сопровождения. Можно ввести свои классы и иерархию на них — тогда не будет связи с MIDL-овской иерархией.
Так что пусть будут шаблоны, это меньшее зло.
SDM>И еще, а как оно развернется компилятором: создаст мне N реализаций одного и того же IBaseImpl или всетаки сделает одну?
Для каждого интерфейса IMyInterface (т.е. для каждого параметра шаблона) будет свой класс IBaseImpl<IMyInterface> с реализацией функций IBase. Если функции большие и постоянные можно сделать то, что делает ATL при подобной ситуации.
Пример оттуда: IPersistStreamInitImpl<T> функция Load, IPersistStreamInit_Load и AtlIPersistStreamInit_Load с минимальными издержками.
Здравствуйте Vi2, Вы писали:
Vi2>Так что пусть будут шаблоны, это меньшее зло.
Проникся.
Vi2>Для каждого интерфейса IMyInterface (т.е. для каждого параметра шаблона) будет свой класс IBaseImpl<IMyInterface> с реализацией функций IBase. Если функции большие и постоянные можно сделать то, что делает ATL при подобной ситуации.
Просветление наступило
Я вообще-то уже начинал подумывать в эту сторону, но то что в Delphi все чудно наследуется, меня остановило
Здравствуйте Vi2, Вы писали:
Vi2>У тебя все структуры IBase и все IMyInterface-ы определены в h-файле от MIDLа, и соотношение между ними установлены. Вклиниться туда нет возможности без потери сопровождения. Можно ввести свои классы и иерархию на них — тогда не будет связи с MIDL-овской иерархией.
Кстати, пришло в голову. Не пробовал, сразу говорю.
Определение IBase компилируется в зависимости от __IBase_FWD_DEFINED__ и __IBase_INTERFACE_DEFINED__ в h-файле. Дальше иерархия классов настраивается на этот класс, так что, если их определить до включения h-файле, то можно в принципе дать своё определение класса IBase как класса не с чистыми функциями, а определёнными как в IBaseImpl выше. Вроде бы так должна реализация вставляться.
Здравствуйте Vi2, Вы писали:
Vi2>Определение IBase компилируется в зависимости от __IBase_FWD_DEFINED__ и __IBase_INTERFACE_DEFINED__ в h-файле. Дальше иерархия классов настраивается на этот класс, так что, если их определить до включения h-файле, то можно в принципе дать своё определение класса IBase как класса не с чистыми функциями, а определёнными как в IBaseImpl выше. Вроде бы так должна реализация вставляться.
Ага, только если это attributed проект/класс тады ой