Большое спасибо всем откликнувшимся!
Отвечаю на возникшие вопросы:
>> Т.е. AddRef и Release реализованы в IInitDone?
Нет, они реализованы в классе Component и являются открытыми (была опечатка, сорри!). В этом классе я хочу частично реализовать интерфейс IUnknown, его часть, отвечающую за подсчет ссылок, часть которая неизменна от компонента к компоненту. Реализацию QueryInterface я хочу оставить конкретному компоненту (в данном случае InitDone). Она изменяется в зависимости от компонента, потому что компонент может поддерживать различные наборы интерфейсов.
>> Можно применить виртуальное наследование, если оверхед приемлем:
Это невозможно, потому что нельзя переопределять интерфейсы, они все унаследованы от IUnknown, причем не виртуально.
>> либо продублировать виртуальные функции в InitDone со ссылкой на Component
Такой подход очень нежелателен, поскольку в компоненте приходится реализовывать весь интерфейс IUnknown, что очень некрасиво, даже если это реализация посредствам Component, ведь функциональность связанная с подсчетом ссылок идентична во всех компонентах.
>> реализуй в class Component метод QueryInterface пустым, похоже, что именно этот класс не компилируется.
Метод QueryInterface должен быть реализован в конкретном компоненте, поскольку его реализация зависит от конкретного компонента.
Component - IUnknown
/
InitDone
IInitDone - IUnknown
>> Это проблема уже сама по себе, неясно, к какому именно IUnknown приводить InitDone неявно.
Как это? IUnknown же является интерфейсом, то есть содержит только чисто-виртуальные функции. Какая разница откуда унаследуется IUnknown, он ведь только определяет функции, а не реализует их.
>> InitDone как раз реализует интерфейс IInitDone, то есть не абстрактный
>> Поэтому предположение об области видимости AddRef() и Release(), я думаю в силе.
Да, наверно проблема с областью видимоти. Как вот ее задать?