Модель программирования Component Object Model. Разработка COM-сервера, страница 17

C* operator->() { return ptr; } // Перенаправляем вызов с помощью стрелки

void Help() { cout<<"\nHelping"; } // Обычный метод

};

void main ()

{

C* p = new C();

Smart sp(p);       // Создание и инициализация smart-указателя

sp->Do();   // Эквивалентно p->Do();Вызывается метод класса С

sp.Help()   // Вызывается метод класса Smart

}

С помощью sp (а точнее, с помощью операции -> и указателя ptr, который в нем хранится), можно вызвать любой метод класса C. Важно что для объекта класса Smart операция -> означает вызов метода класса C, а доступ к методам самого класса Smart осуществляется с помощью точки, а не стрелки. Кроме того, в классе Smart нет необходимости явно перечислять все методы класса C. Аналогичная идея используется и для доступа к методам интерфейса ISay. Класс ISayPtr, скроенный по шаблону  _com_ptr_t, значительно более умен, чем класс Smart, но он использует тот же механизм работы со встроенным указателем.

Цель использования умного указателя ISayPtr — избавить пользователя от необходимости знать глупый номерок IID_ISay, следить за счетчиком ссылок на интерфейс ISay (то есть вызывать методы AddRef и Release), а также устранить необходимость вызова функции CoCreateInstance. Заботы о выполнении всех этих операций берет на себя новый класс ISayPtr. Он, таким образом, скрывает от пользователя рутинную часть работы с объектом COM, оставляя лишь творческую. В этом и заключается смысл качественной характеристики smart pointer ("сообразительный" указатель).

Заметим, что библиотека ATL (ActiveX Template Library) имеет два шаблона классов CComQIPtr и CComPtr, которые способны создавать классы умных указателей и помогать работать с ними. В MFC тоже есть недокументированный шаблон класса CIP (см. файл AFXCOM_.H), который упрощает те же рутинные операции COM. Подведем итог.

¨  COM-интерфейс первоначально представлен в виде базового абстрактного класса, методы которого раскрываются с помощью ко-класса.

¨  При использовании библиотеки типов некоторые из его чисто виртуальных функций заменяются на невиртуальные inline-функции класса-обертки, которые внутри содержат вызовы виртуальных функций и затем проверяют код ошибки.

¨  В случае сбоя вызывается обработчик ошибок _com_issue_errorex. Таким образом, smart pointers помогают обрабатывать ошибки и упрощают поддержку счетчиков ссылок.

¨  В рассматриваемом коде использован специальный класс _bstr_t, предназначенный для работы с Unicode-строками. Он является классом-оберткой для BSTR, упрощающим работу со строками типа BSTR. Теперь можно не заботиться о вызове функции SysFreeString, так как эту работу берет на себя класс _bstr_t.


Проект на основе ATL

ATL (Active Template Library) — это библиотека шаблонов функций и классов, которая разработана с целью упрощения и ускорения разработки COM-объектов. Несмотря на заявления о том, что ATL не является альтернативой MFC, а лишь дополняет ее, побудительной причиной разработки этой библиотеки был тот факт, что объекты COM, разработанные с помощью MFC, и внедренные в HTML-документ, работали слишком медленно.

Наследование от CObject и все те удобства, которые оно приносит, обходятся слишком дорого (в смысле быстродействия) и в условиях Web-страниц. Объекты MFC-происхождения проигрывают объектам, разработанным с помощью COM API. В библиотеке ATL не используется наследование от CObject и некоторые другие принципы построения классов, характерные для MFC. За счет этого удалось повысить эффективность работы COM-объектов и ускорить их функционирование даже в условиях Web-страниц.

Создайте новый проект типа ATL Project под именем ATest. Для этого:

1.  Дайте команду File4New4Projects и выберите нужный тип, местоположение и имя проекта. Нажмите OK;

2.  В окне мастера все флажки должны быть в выключенном состоянии, кроме флага выбора типа сервера — Dynamic Link Library (DLL). Обязательно снимите флажок Attributed.

3.  Нажмите Finish.