Наследование от класса COM - PullRequest
1 голос
/ 01 августа 2011

Я работаю в Visual Studio 2005 с чисто неуправляемым проектом (C ++).У меня есть класс COM, от третьей стороны, в файле OCX.Этот класс является элементом управления («виджет»).Я использовал его через класс-оболочку IDispatch, сгенерированный с использованием Add Class из Typelib Wizard.

Я хотел бы расширить этот класс несколькими способами, и публичное наследование будет гораздо более практичным, чем композитирование (я хочупроизводный объект, чтобы показать каждый метод, который делает родительский класс).Производный класс также должен быть доступен как компонент COM.

Можно ли это сделать?Если положительный, как я могу сделать это?

Ответы [ 2 ]

3 голосов
/ 02 августа 2011

Невозможно наследовать от COM-классов, как вы можете в C ++.Однако есть обходные пути:

Агрегаты COM полезны, только если вы хотите добавить интерфейс (с реализацией) к существующему классу COM.Вы не можете перехватывать вызовы к агрегированному объекту.

Переадресация означает, что если у вас есть интерфейс IExistingInterface, вы реализуете свой собственный класс, который реализует IExistingInterface.В вашем классе вы сохраняете ссылку на экземпляр объекта, от которого хотите «наследовать».В вашей реализации IExistingInterface вы перенаправляете вызовы в соответствии с «унаследованным» объектом.Этот метод дает вам полный контроль.

Пример: (псевдокод!)

class MyClass : IExistingInterface {
    IExistingInterface* m_pInherited;
public:
    MyClass() {
        ::CoCreateInstance(CLSID_OtherImplementation, ..., ..., IID_IExistingInterface, (void**)&m_pInherited);
    }

    // IExistingInterface methods
    HRESULT MethodX() {
        // Do some pre processing
        HRESULT hr = m_pInherited->MethodX();
        if(FAILED(hr))
            return hr;

        // Do some post processing
        return S_OK;
   }
};

Редактировать: Я действительно рекомендую использовать ATL для создания COM-компонента.,В этом случае создайте «унаследованный» объект в FinalConstruct(), а не в конструкторе C ++.

1 голос
/ 02 августа 2011

Вы можете создать новый интерфейс, производный от первого.Ваша функция QueryInterface должна будет ответить на оба идентификатора GUID и доставить правильный указатель.Как только вы это сделаете, попросите ваш конкретный класс реализовать расширенный набор функций (т. Е. Весь второй интерфейс, включая все, что унаследовано от первого.)

Если ваш конкретный класс также наследует от конкретного классав библиотеке у вас будет шаблон наследования алмазов.Вы можете найти решения для этого, я бы начал здесь: Алмазное наследование (C ++)

...