Обновить
Комментарии 11
Меня тоже смутил этот факт, так как я успешно наследовался от коклассов. Хотелось бы, чтобы автор прояснил этот момент.
Были ли эти коклассы написаны на одном языке, собраны одним компилятором и собирался ли потомок с использованием исходного кода предка?
Не знаю, как это делал Xitsa, но в COM имеется языконезависимый механизм.
Называется этот механизм «агрегация» или «агрегирование» (aggregation)
Да, но это не то же самое. Нельзя взять какой–нибудь базовый кокласс, как–нибудь без проблем агрегировать его, добавить своих функций и использовать как аргумент метода, ожидающий предка (а не интерфейс предка). На одних интерфейсах всего не сделаешь, часто нужно, чтобы полученный объект имел не только фиксированный интерфейс, но и особенность реализации внутри себя. Ну, скажем, нельзя реализовать какой–нибудь не предназначенный для этого интерфейс Office и передать этот фальшивый объект настоящему объекту Office как аргумент. Или, если написать COM–версию ASIO, то рано или поздно дело дойдёт до select(), и потребуются OS–специфичная информация.

При наследовании предок управляет тем, какие интерфейсы будут у потомка, и набор этих интерфейсов может измениться без участия потомка. При агрегации только контейнер единолично решает, какой набор интерфейсов он поддерживает, реализуя сам или делегируя одному из агрегированных объектов. Даже, если переписать эту логику на обратную: все интерфейсы, которые мы не знаем, направлять на делегацию внутреннему объекту, среди этих неизвестных интерфейсов может оказаться следующая версия интерфейса объекта, и в этом случае нужно что–то сделать, чтобы старые методы этого неизвестного интерфейса обрабатывались контейнером. Это можно сделать при помощи кооперации со стороны внутреннего объекта. Наверное, ничего неразрешимого, но дело в том, что это не является продуманным вариантом использования COM, и, если работать в этом направлении, то будет написан новый код, который частью COM не будет, и, учитывая все уровни косвенности, результат будет хуже, чем если с самого начала делать объектную систему, поддерживающую весь набор трансформаций.
Вы путаете две ситуации:

1. Берем базовый класс (A), расширяем его (Б) и передаем третьему компоненту (В), ожидающему А.
2. Берем базовый класс (А), расширяем его (Б) и возвращаем его той же самой библиотеке, в которой находится А.

Так вот, первая ситуация в COM решается без особых проблем. Вторая же зачастую вообще невозможна в статически типизированных языках (попробуйте в Java от SelectableChannel унаследоваться, чтобы его потом Selector распознал).

Что же по поводу внезапно появившегося нового интерфейса в базовом классе — все современные языки подвержены той же самой проблеме, но только с внезапно появившимися методами.
Как можно расширить базовый класс средствами только COM?

У нас есть возможность получить из чужой библиотеки готовый экземпляр кокласса или же фабрику, которая сделает экземпляр. Переделать уже созданный экземпляр в его как бы потомка без агрегации не представляется возможным.
кокласс был написан на С++, наследник на .Net.
По сути это вариант агрегации.
потребовалась кооперация от кокласса, чтобы при переопределении методов кокласс мог их вызывать.
Я, наверное, уточню ситуацию:
У нас есть свой скриптовый язык на базе .Net, на котором можно писать пользовательские обработчики событий.
Для того, чтобы добавление новых событий не приводило к неработоспособности старых вариантов был сделан кокласс–стандартный обработчик. И пользовательский класс наследовал от кокласса стандартным для .Net'а способом.

Для того, чтобы кокласс мог вызывать методы унаследованного класса, для this делался QueryInterface и вызывались методы у полученного интерфейса.
Плохо, что эта вещь не является drop-in replacement. Когда вышел SOM 2.0, это не сломало приложения, использующие SOM 1.0, хотя у первого и второго были существенные отличия. NOM не продолжает эту традицию. NOM плохо документирован и существует в большей степени не сам по себе, а ради того, чтобы был сделан Voyager, кроссплатформенный аналог WPS. Из того, что я читал про WPS, помню, что SOM там используется по–особенному, не полностью, и, если, например, использовать множественное наследование, WPS падает. В связи с чем напрашивается вопрос, а не будет ли NOM таким же недо–SOM, который применяется в WPS?

Сильно смущает обязательная сборка мусора в NOM
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.